1 // Copyright (c) 2015-2016 The Khronos Group Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SOURCE_DIAGNOSTIC_H_ 16 #define SOURCE_DIAGNOSTIC_H_ 17 18 #include <sstream> 19 #include <string> 20 21 #include "spirv-tools/libspirv.hpp" 22 23 namespace spvtools { 24 25 // A DiagnosticStream remembers the current position of the input and an error 26 // code, and captures diagnostic messages via the left-shift operator. 27 // If the error code is not SPV_FAILED_MATCH, then captured messages are 28 // emitted during the destructor. 29 class DiagnosticStream { 30 public: DiagnosticStream(spv_position_t position,const MessageConsumer & consumer,const std::string & disassembled_instruction,spv_result_t error)31 DiagnosticStream(spv_position_t position, const MessageConsumer& consumer, 32 const std::string& disassembled_instruction, 33 spv_result_t error) 34 : position_(position), 35 consumer_(consumer), 36 disassembled_instruction_(disassembled_instruction), 37 error_(error) {} 38 39 // Creates a DiagnosticStream from an expiring DiagnosticStream. 40 // The new object takes the contents of the other, and prevents the 41 // other from emitting anything during destruction. 42 DiagnosticStream(DiagnosticStream&& other); 43 44 // Destroys a DiagnosticStream. 45 // If its status code is something other than SPV_FAILED_MATCH 46 // then emit the accumulated message to the consumer. 47 ~DiagnosticStream(); 48 49 // Adds the given value to the diagnostic message to be written. 50 template <typename T> 51 DiagnosticStream& operator<<(const T& val) { 52 stream_ << val; 53 return *this; 54 } 55 56 // Conversion operator to spv_result, returning the error code. spv_result_t()57 operator spv_result_t() { return error_; } 58 59 private: 60 std::ostringstream stream_; 61 spv_position_t position_; 62 MessageConsumer consumer_; // Message consumer callback. 63 std::string disassembled_instruction_; 64 spv_result_t error_; 65 }; 66 67 // Changes the MessageConsumer in |context| to one that updates |diagnostic| 68 // with the last message received. 69 // 70 // This function expects that |diagnostic| is not nullptr and its content is a 71 // nullptr. 72 void UseDiagnosticAsMessageConsumer(spv_context context, 73 spv_diagnostic* diagnostic); 74 75 std::string spvResultToString(spv_result_t res); 76 77 } // namespace spvtools 78 79 #endif // SOURCE_DIAGNOSTIC_H_ 80