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: |
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. |
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 | |