namespace libspirv {
DiagnosticStream::~DiagnosticStream() {
- using spvtools::MessageLevel;
if (error_ != SPV_FAILED_MATCH && consumer_ != nullptr) {
- auto level = MessageLevel::kError;
+ auto level = spvtools::SPV_MSG_ERROR;
switch (error_) {
case SPV_SUCCESS:
case SPV_REQUESTED_TERMINATION: // Essentially success.
- level = MessageLevel::kInfo;
+ level = spvtools::SPV_MSG_INFO;
break;
case SPV_WARNING:
- level = MessageLevel::kWarning;
+ level = spvtools::SPV_MSG_WARNINING;
break;
case SPV_UNSUPPORTED:
case SPV_ERROR_INTERNAL:
case SPV_ERROR_INVALID_TABLE:
- level = MessageLevel::kInternalError;
+ level = spvtools::SPV_MSG_INTERNAL_ERROR;
break;
case SPV_ERROR_OUT_OF_MEMORY:
- level = MessageLevel::kFatal;
+ level = spvtools::SPV_MSG_FATAL;
break;
default:
break;
spv_diagnostic* diagnostic) {
assert(diagnostic && *diagnostic == nullptr);
- auto create_diagnostic = [diagnostic](spvtools::MessageLevel, const char*,
- const spv_position_t& position,
- const char* message) {
+ auto create_diagnostic = [diagnostic](
+ spvtools::spv_message_level_t, const char*,
+ const spv_position_t& position, const char* message) {
auto p = position;
spvDiagnosticDestroy(*diagnostic); // Avoid memory leak.
*diagnostic = spvDiagnosticCreate(&p, message);
namespace spvtools {
-std::string StringifyMessage(MessageLevel level, const char* source,
+std::string StringifyMessage(spv_message_level_t level, const char* source,
const spv_position_t& position,
const char* message) {
const char* level_string = nullptr;
switch (level) {
- case MessageLevel::kFatal:
+ case SPV_MSG_FATAL:
level_string = "fatal";
break;
- case MessageLevel::kInternalError:
+ case SPV_MSG_INTERNAL_ERROR:
level_string = "internal error";
break;
- case MessageLevel::kError:
+ case SPV_MSG_ERROR:
level_string = "error";
break;
- case MessageLevel::kWarning:
+ case SPV_MSG_WARNINING:
level_string = "warning";
break;
- case MessageLevel::kInfo:
+ case SPV_MSG_INFO:
level_string = "info";
break;
- case MessageLevel::kDebug:
+ case SPV_MSG_DEBUG:
level_string = "debug";
break;
}
// TODO(antiagainst): This eventually should be in the C++ interface.
// Severity levels of messages communicated to the consumer.
-enum MessageLevel {
- kFatal, // Unrecoverable error due to environment.
- // Will exit the program immediately. E.g.,
- // out of memory.
- kInternalError, // Unrecoverable error due to SPIRV-Tools internals.
- // Will exit the program immediately. E.g.,
- // unimplemented feature.
- kError, // Normal error due to user input.
- kWarning, // Warning information.
- kInfo, // General information.
- kDebug, // Debug information.
-};
+typedef enum spv_message_level_t {
+ SPV_MSG_FATAL, // Unrecoverable error due to environment.
+ // Will exit the program immediately. E.g.,
+ // out of memory.
+ SPV_MSG_INTERNAL_ERROR, // Unrecoverable error due to SPIRV-Tools
+ // internals.
+ // Will exit the program immediately. E.g.,
+ // unimplemented feature.
+ SPV_MSG_ERROR, // Normal error due to user input.
+ SPV_MSG_WARNINING, // Warning information.
+ SPV_MSG_INFO, // General information.
+ SPV_MSG_DEBUG, // Debug information.
+} spv_message_level_t;
// Message consumer. The C strings for source and message are only alive for the
// specific invocation.
using MessageConsumer = std::function<void(
- MessageLevel /* level */, const char* /* source */,
+ spv_message_level_t /* level */, const char* /* source */,
const spv_position_t& /* position */, const char* /* message */
)>;
// A message consumer that ignores all messages.
-inline void IgnoreMessage(MessageLevel, const char*, const spv_position_t&,
- const char*) {}
+inline void IgnoreMessage(spv_message_level_t, const char*,
+ const spv_position_t&, const char*) {}
// A helper function to compose and return a string from the message in the
// following format:
// "<level>: <source>:<line>:<column>:<index>: <message>"
-std::string StringifyMessage(MessageLevel level, const char* source,
+std::string StringifyMessage(spv_message_level_t level, const char* source,
const spv_position_t& position,
const char* message);
// Logs an error message to the consumer saying the given feature is
// unimplemented.
-#define SPIRV_UNIMPLEMENTED(consumer, feature) \
- do { \
- spvtools::Log(consumer, MessageLevel::kInternalError, __FILE__, \
- {__LINE__, 0, 0}, "unimplemented: " feature); \
+#define SPIRV_UNIMPLEMENTED(consumer, feature) \
+ do { \
+ spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
+ {__LINE__, 0, 0}, "unimplemented: " feature); \
} while (0)
// Logs an error message to the consumer saying the code location
// should be unreachable.
-#define SPIRV_UNREACHABLE(consumer) \
- do { \
- spvtools::Log(consumer, MessageLevel::kInternalError, __FILE__, \
- {__LINE__, 0, 0}, "unreachable"); \
+#define SPIRV_UNREACHABLE(consumer) \
+ do { \
+ spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
+ {__LINE__, 0, 0}, "unreachable"); \
} while (0)
// Helper macros for concatenating arguments.
// Calls the given |consumer| by supplying the |message|. The |message| is from
// the given |file| and |location| and of the given severity |level|.
-inline void Log(const MessageConsumer& consumer, MessageLevel level,
+inline void Log(const MessageConsumer& consumer, spv_message_level_t level,
const char* file, const spv_position_t& position,
const char* message) {
if (consumer != nullptr) consumer(level, file, position, message);
// given |format|. The |message| is from the given |file| and |location| and of
// the given severity |level|.
template <typename... Args>
-void Logf(const MessageConsumer& consumer, MessageLevel level, const char* file,
- const spv_position_t& position, const char* format, Args&&... args) {
+void Logf(const MessageConsumer& consumer, spv_message_level_t level,
+ const char* file, const spv_position_t& position, const char* format,
+ Args&&... args) {
#if defined(_MSC_VER) && _MSC_VER < 1900
// Sadly, snprintf() is not supported until Visual Studio 2015!
#define snprintf _snprintf
#define SPIRV_ASSERT_1(consumer, condition) \
do { \
if (!(condition)) { \
- spvtools::Log(consumer, MessageLevel::kInternalError, __FILE__, \
+ spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
{__LINE__, 0, 0}, "assertion failed: " #condition); \
std::exit(EXIT_FAILURE); \
} \
} while (0)
-#define SPIRV_ASSERT_2(consumer, condition, message) \
- do { \
- if (!(condition)) { \
- spvtools::Log(consumer, MessageLevel::kInternalError, __FILE__, \
- {__LINE__, 0, 0}, "assertion failed: " message); \
- std::exit(EXIT_FAILURE); \
- } \
+#define SPIRV_ASSERT_2(consumer, condition, message) \
+ do { \
+ if (!(condition)) { \
+ spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
+ {__LINE__, 0, 0}, "assertion failed: " message); \
+ std::exit(EXIT_FAILURE); \
+ } \
} while (0)
-#define SPIRV_ASSERT_more(consumer, condition, format, ...) \
- do { \
- if (!(condition)) { \
- spvtools::Logf(consumer, MessageLevel::kInternalError, __FILE__, \
- {__LINE__, 0, 0}, "assertion failed: " format, \
- __VA_ARGS__); \
- std::exit(EXIT_FAILURE); \
- } \
+#define SPIRV_ASSERT_more(consumer, condition, format, ...) \
+ do { \
+ if (!(condition)) { \
+ spvtools::Logf(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
+ {__LINE__, 0, 0}, "assertion failed: " format, \
+ __VA_ARGS__); \
+ std::exit(EXIT_FAILURE); \
+ } \
} while (0)
#define SPIRV_ASSERT_3(consumer, condition, format, ...) \
#define SPIRV_ASSERT_5(consumer, condition, format, ...) \
SPIRV_ASSERT_more(consumer, condition, format, __VA_ARGS__)
-#define SPIRV_DEBUG_1(consumer, message) \
- do { \
- spvtools::Log(consumer, MessageLevel::Debug, __FILE__, {__LINE__, 0, 0}, \
- message); \
+#define SPIRV_DEBUG_1(consumer, message) \
+ do { \
+ spvtools::Log(consumer, SPV_MSG_DEBUG, __FILE__, {__LINE__, 0, 0}, \
+ message); \
} while (0)
-#define SPIRV_DEBUG_more(consumer, format, ...) \
- do { \
- spvtools::Logf(consumer, MessageLevel::Debug, __FILE__, {__LINE__, 0, 0}, \
- format, __VA_ARGS__); \
+#define SPIRV_DEBUG_more(consumer, format, ...) \
+ do { \
+ spvtools::Logf(consumer, SPV_MSG_DEBUG, __FILE__, {__LINE__, 0, 0}, \
+ format, __VA_ARGS__); \
} while (0)
#define SPIRV_DEBUG_2(consumer, format, ...) \
auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- ctx, [&invocation](spvtools::MessageLevel, const char*,
+ ctx, [&invocation](spvtools::spv_message_level_t, const char*,
const spv_position_t&, const char*) { ++invocation; });
EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS));
auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- ctx, [&invocation](spvtools::MessageLevel level, const char* source,
- const spv_position_t& position, const char* message) {
+ ctx,
+ [&invocation](spvtools::spv_message_level_t level, const char* source,
+ const spv_position_t& position, const char* message) {
++invocation;
- EXPECT_EQ(spvtools::MessageLevel::kError, level);
+ EXPECT_EQ(spvtools::SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- ctx, [&invocation](spvtools::MessageLevel, const char*,
+ ctx, [&invocation](spvtools::spv_message_level_t, const char*,
const spv_position_t&, const char*) { ++invocation; });
EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS));
auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- ctx, [&invocation](spvtools::MessageLevel, const char*,
+ ctx, [&invocation](spvtools::spv_message_level_t, const char*,
const spv_position_t&, const char*) { ++invocation; });
words.push_back(0xffffffff); // Certainly invalid instruction header.
libspirv::IdTypeClass type) {
spv_instruction_t inst;
std::string message;
- auto capture_message = [&message](spvtools::MessageLevel, const char*,
+ auto capture_message = [&message](spvtools::spv_message_level_t, const char*,
const spv_position_t&,
const char* m) { message = m; };
libspirv::IdType expected_type{test.bitwidth, test.is_signed, type};
libspirv::IdTypeClass type) {
spv_instruction_t inst;
std::string message;
- auto capture_message = [&message](spvtools::MessageLevel, const char*,
+ auto capture_message = [&message](spvtools::spv_message_level_t, const char*,
const spv_position_t&,
const char* m) { message = m; };
libspirv::IdType expected_type{test.bitwidth, test.is_signed, type};
// TODO(antiagainst): Use public C API for setting the consumer once exists.
SetContextMessageConsumer(
context,
- [&invocation](MessageLevel level, const char* source,
+ [&invocation](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
// The error happens at scanning the begining of second line.
EXPECT_STREQ("input", source);
EXPECT_EQ(1u, position.line);
int invocation = 0;
SetContextMessageConsumer(
context,
- [&invocation](MessageLevel level, const char* source,
+ [&invocation](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
int invocation = 0;
SetContextMessageConsumer(
context,
- [&invocation](MessageLevel level, const char* source,
+ [&invocation](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- context, [&invocation](MessageLevel, const char*, const spv_position_t&,
- const char*) { ++invocation; });
+ context,
+ [&invocation](spv_message_level_t, const char*, const spv_position_t&,
+ const char*) { ++invocation; });
spv_binary binary = nullptr;
spv_diagnostic diagnostic = nullptr;
auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- context, [&invocation](MessageLevel, const char*, const spv_position_t&,
- const char*) { ++invocation; });
+ context,
+ [&invocation](spv_message_level_t, const char*, const spv_position_t&,
+ const char*) { ++invocation; });
spv_binary binary = nullptr;
ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(context, input_text,
auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
SetContextMessageConsumer(
- context, [&invocation](MessageLevel, const char*, const spv_position_t&,
- const char*) { ++invocation; });
+ context,
+ [&invocation](spv_message_level_t, const char*, const spv_position_t&,
+ const char*) { ++invocation; });
spv_binary binary = nullptr;
ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(context, input_text,
EXPECT_EQ(SpvVersion, binary[1]);
// This cannot pass validation since %1 is not defined.
- t.SetMessageConsumer([](MessageLevel level, const char* source,
+ t.SetMessageConsumer([](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
SpvTools t(SPV_ENV_UNIVERSAL_1_0);
int invocation_count = 0;
t.SetMessageConsumer(
- [&invocation_count](MessageLevel level, const char* source,
+ [&invocation_count](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation_count;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(5u, position.column);
SpvTools t(SPV_ENV_UNIVERSAL_1_1);
int invocation_count = 0;
t.SetMessageConsumer(
- [&invocation_count](MessageLevel level, const char* source,
+ [&invocation_count](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation_count;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
SpvTools t10(SPV_ENV_UNIVERSAL_1_0);
int invocation_count = 0;
t10.SetMessageConsumer(
- [&invocation_count](MessageLevel level, const char* source,
+ [&invocation_count](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation_count;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
"OpCapability Shader\nOpMemoryModel Logical GLSL450";
SpvTools t(SPV_ENV_UNIVERSAL_1_1);
int invocation_count = 0;
- t.SetMessageConsumer(
- [&invocation_count](MessageLevel, const char*, const spv_position_t&,
- const char*) { ++invocation_count; });
+ t.SetMessageConsumer([&invocation_count](spv_message_level_t, const char*,
+ const spv_position_t&, const char*) {
+ ++invocation_count;
+ });
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text, &binary));
SpvTools t(SPV_ENV_UNIVERSAL_1_1);
int invocation_count = 0;
t.SetMessageConsumer(
- [&invocation_count](MessageLevel level, const char* source,
+ [&invocation_count](spv_message_level_t level, const char* source,
const spv_position_t& position, const char* message) {
++invocation_count;
- EXPECT_EQ(MessageLevel::kError, level);
+ EXPECT_EQ(SPV_MSG_ERROR, level);
EXPECT_STREQ("input", source);
EXPECT_EQ(0u, position.line);
EXPECT_EQ(0u, position.column);
TEST(Log, Unimplemented) {
int invocation = 0;
- auto consumer = [&invocation](MessageLevel level, const char* source,
+ auto consumer = [&invocation](spv_message_level_t level, const char* source,
const spv_position_t&, const char* message) {
++invocation;
- EXPECT_EQ(MessageLevel::kInternalError, level);
+ EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level);
EXPECT_THAT(source, MatchesRegex(".*test_log.cpp$"));
EXPECT_STREQ("unimplemented: the-ultimite-feature", message);
};
TEST(Log, Unreachable) {
int invocation = 0;
- auto consumer = [&invocation](MessageLevel level, const char* source,
+ auto consumer = [&invocation](spv_message_level_t level, const char* source,
const spv_position_t&, const char* message) {
++invocation;
- EXPECT_EQ(MessageLevel::kInternalError, level);
+ EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level);
EXPECT_THAT(source, MatchesRegex(".*test_log.cpp$"));
EXPECT_STREQ("unreachable", message);
};
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_1;
opt::PassManager pass_manager;
- pass_manager.SetMessageConsumer([](MessageLevel level, const char* source,
- const spv_position_t& position,
- const char* message) {
- std::cerr << StringifyMessage(level, source, position, message);
- });
+ pass_manager.SetMessageConsumer(
+ [](spv_message_level_t level, const char* source,
+ const spv_position_t& position, const char* message) {
+ std::cerr << StringifyMessage(level, source, position, message);
+ });
for (int argi = 1; argi < argc; ++argi) {
const char* cur_arg = argv[argi];