diff --git a/include/libspirv/libspirv.h b/include/libspirv/libspirv.h index 6f88b1c6..60007c45 100644 --- a/include/libspirv/libspirv.h +++ b/include/libspirv/libspirv.h @@ -362,6 +362,7 @@ typedef struct spv_position_t { typedef struct spv_diagnostic_t { spv_position_t position; char *error; + bool isTextSource; } spv_diagnostic_t; // Type Definitions diff --git a/source/diagnostic.cpp b/source/diagnostic.cpp index a6f87aa6..1f51b39a 100644 --- a/source/diagnostic.cpp +++ b/source/diagnostic.cpp @@ -42,6 +42,7 @@ spv_diagnostic spvDiagnosticCreate(const spv_position position, diagnostic->error = new char[length]; spvCheck(!diagnostic->error, delete diagnostic; return nullptr); diagnostic->position = *position; + diagnostic->isTextSource = false; memset(diagnostic->error, 0, length); strncpy(diagnostic->error, message, length); return diagnostic; @@ -58,10 +59,7 @@ void spvDiagnosticDestroy(spv_diagnostic diagnostic) { spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) { spvCheck(!diagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC); - // TODO: Check that the logic choosing between a text or binary diagnostic is - // corrent. - if ((diagnostic->position.line || diagnostic->position.column) && - diagnostic->position.index) { + if (diagnostic->isTextSource) { // NOTE: This is a text position // NOTE: add 1 to the line as editors start at line 1, we are counting new // line characters to start at line 0 @@ -69,9 +67,8 @@ spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) { << diagnostic->position.column + 1 << ": " << diagnostic->error << "\n"; return SPV_SUCCESS; - } else if (!diagnostic->position.line && !diagnostic->position.column && - diagnostic->position.index) { - // NOTE: This is a binary position + } else { + // NOTE: Assume this is a binary position std::cerr << "error: " << diagnostic->position.index << ": " << diagnostic->error << "\n"; return SPV_SUCCESS; diff --git a/source/text.cpp b/source/text.cpp index 4fefcfd8..d06c55c3 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -186,8 +186,10 @@ spv_result_t spvTextWordGet(const spv_text text, } } +namespace { + // Returns true if the string at the given position in text starts with "Op". -static bool spvStartsWithOp(const spv_text text, const spv_position position) { +bool spvStartsWithOp(const spv_text text, const spv_position position) { if (text->length < position->index + 3) return false; char ch0 = text->str[position->index]; char ch1 = text->str[position->index + 1]; @@ -195,6 +197,8 @@ static bool spvStartsWithOp(const spv_text text, const spv_position position) { return ('O' == ch0 && 'p' == ch1 && ('A' <= ch2 && ch2 <= 'Z')); } +} // anonymous namespace + // Returns true if a new instruction begins at the given position in text. bool spvTextIsStartOfNewInst(const spv_text text, const spv_position position) { @@ -670,11 +674,17 @@ spv_result_t spvTextEncodeOpcode( return SPV_SUCCESS; } -spv_result_t spvTextToBinary(const spv_text text, - const spv_opcode_table opcodeTable, - const spv_operand_table operandTable, - const spv_ext_inst_table extInstTable, - spv_binary *pBinary, spv_diagnostic *pDiagnostic) { +namespace { + +// Translates a given assembly language module into binary form. +// If a diagnostic is generated, it is not yet marked as being +// for a text-based input. +spv_result_t spvTextToBinaryInternal(const spv_text text, + const spv_opcode_table opcodeTable, + const spv_operand_table operandTable, + const spv_ext_inst_table extInstTable, + spv_binary *pBinary, + spv_diagnostic *pDiagnostic) { spv_position_t position = {}; spvCheck(!text->str || !text->length, DIAGNOSTIC << "Text stream is empty."; return SPV_ERROR_INVALID_TEXT); @@ -742,6 +752,20 @@ spv_result_t spvTextToBinary(const spv_text text, return SPV_SUCCESS; } +} // anonymous namespace + +spv_result_t spvTextToBinary(const spv_text text, + const spv_opcode_table opcodeTable, + const spv_operand_table operandTable, + const spv_ext_inst_table extInstTable, + spv_binary *pBinary, spv_diagnostic *pDiagnostic) { + spv_result_t result = spvTextToBinaryInternal( + text, opcodeTable, operandTable, extInstTable, pBinary, pDiagnostic); + if (pDiagnostic && *pDiagnostic) (*pDiagnostic)->isTextSource = true; + + return result; +} + void spvTextDestroy(spv_text text) { spvCheck(!text, return ); if (text->str) { diff --git a/test/DiagnosticPrint.cpp b/test/DiagnosticPrint.cpp index 9fe27928..f9fdf323 100644 --- a/test/DiagnosticPrint.cpp +++ b/test/DiagnosticPrint.cpp @@ -41,4 +41,7 @@ TEST(DiagnosticPrint, InvalidDiagnostic) { ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC, spvDiagnosticPrint(nullptr)); } +// TODO(dneto): We should be able to redirect the diagnostic printing. +// Once we do that, we can test diagnostic corner cases. + } // anonymous namespace