/src/abseil-cpp/absl/log/internal/log_message.h
Line | Count | Source |
1 | | // Copyright 2022 The Abseil Authors. |
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 | | // https://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 | | // ----------------------------------------------------------------------------- |
16 | | // File: log/internal/log_message.h |
17 | | // ----------------------------------------------------------------------------- |
18 | | // |
19 | | // This file declares `class absl::log_internal::LogMessage`. This class more or |
20 | | // less represents a particular log message. LOG/CHECK macros create a temporary |
21 | | // instance of `LogMessage` and then stream values to it. At the end of the |
22 | | // LOG/CHECK statement, the LogMessage is voidified by operator&&, and `Flush()` |
23 | | // directs the message to the registered log sinks. Heap-allocation of |
24 | | // `LogMessage` is unsupported. Construction outside of a `LOG` macro is |
25 | | // unsupported. |
26 | | |
27 | | #ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
28 | | #define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
29 | | |
30 | | #include <wchar.h> |
31 | | |
32 | | #include <cstddef> |
33 | | #include <ios> |
34 | | #include <memory> |
35 | | #include <ostream> |
36 | | #include <streambuf> |
37 | | #include <string> |
38 | | #include <string_view> |
39 | | #include <type_traits> |
40 | | |
41 | | #include "absl/base/attributes.h" |
42 | | #include "absl/base/config.h" |
43 | | #include "absl/base/internal/errno_saver.h" |
44 | | #include "absl/base/log_severity.h" |
45 | | #include "absl/base/nullability.h" |
46 | | #include "absl/log/internal/nullguard.h" |
47 | | #include "absl/log/internal/structured_proto.h" |
48 | | #include "absl/log/log_entry.h" |
49 | | #include "absl/log/log_sink.h" |
50 | | #include "absl/strings/has_absl_stringify.h" |
51 | | #include "absl/strings/string_view.h" |
52 | | #include "absl/time/time.h" |
53 | | #include "absl/types/source_location.h" |
54 | | #include "absl/types/span.h" |
55 | | |
56 | | namespace absl { |
57 | | ABSL_NAMESPACE_BEGIN |
58 | | namespace log_internal { |
59 | | constexpr int kLogMessageBufferSize = 15000; |
60 | | |
61 | | enum class StructuredStringType; |
62 | | |
63 | | class LogMessage { |
64 | | public: |
65 | | struct InfoTag {}; |
66 | | struct WarningTag {}; |
67 | | struct ErrorTag {}; |
68 | | |
69 | | // Used for `LOG`. Taking `const char *` instead of `string_view` keeps |
70 | | // callsites a little bit smaller at the cost of doing `strlen` at runtime. |
71 | | LogMessage(const char* absl_nonnull file, int line, |
72 | | absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD; |
73 | | // Used for FFI integrations that don't have a NUL-terminated string. |
74 | | LogMessage(absl::string_view file, int line, |
75 | | absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD; |
76 | | // These constructors are slightly smaller/faster to call; the severity is |
77 | | // curried into the function pointer. |
78 | | LogMessage(const char* absl_nonnull file, int line, |
79 | | InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
80 | | LogMessage(const char* absl_nonnull file, int line, |
81 | | WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
82 | | LogMessage(const char* absl_nonnull file, int line, |
83 | | ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
84 | | LogMessage(const LogMessage&) = delete; |
85 | | LogMessage& operator=(const LogMessage&) = delete; |
86 | | ~LogMessage() ABSL_ATTRIBUTE_COLD; |
87 | | |
88 | | // Overrides the location inferred from the callsite. The string pointed to |
89 | | // by `file` must be valid until the end of the statement. |
90 | | LogMessage& AtLocation(absl::string_view file, int line); |
91 | | // `loc` doesn't default to `absl::SourceLocation::current()` here since the |
92 | | // callsite is already the default location for `LOG` statements. |
93 | 0 | LogMessage& AtLocation(absl::SourceLocation loc) { |
94 | 0 | return AtLocation(loc.file_name(), static_cast<int>(loc.line())); |
95 | 0 | } |
96 | | // Omits the prefix from this line. The prefix includes metadata about the |
97 | | // logged data such as source code location and timestamp. |
98 | | LogMessage& NoPrefix(); |
99 | | // Sets the verbosity field of the logged message as if it was logged by |
100 | | // `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect |
101 | | // evaluation of the statement when the specified `verbose_level` has been |
102 | | // disabled. The only effect is on `absl::LogSink` implementations which |
103 | | // make use of the `absl::LogSink::verbosity()` value. The value |
104 | | // `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message |
105 | | // not verbose. |
106 | | LogMessage& WithVerbosity(int verbose_level); |
107 | | // Uses the specified timestamp instead of one collected in the constructor. |
108 | | LogMessage& WithTimestamp(absl::Time timestamp); |
109 | | // Uses the specified thread ID instead of one collected in the constructor. |
110 | | LogMessage& WithThreadID(absl::LogEntry::tid_t tid); |
111 | | // Copies all metadata (but no data) from the specified `absl::LogEntry`. |
112 | | LogMessage& WithMetadataFrom(const absl::LogEntry& entry); |
113 | | // Appends to the logged message a colon, a space, a textual description of |
114 | | // the current value of `errno` (as by strerror(3)), and the numerical value |
115 | | // of `errno`. |
116 | | LogMessage& WithPerror(); |
117 | | // Sends this message to `*sink` in addition to whatever other sinks it would |
118 | | // otherwise have been sent to. |
119 | | LogMessage& ToSinkAlso(absl::LogSink* absl_nonnull sink); |
120 | | // Sends this message to `*sink` and no others. |
121 | | LogMessage& ToSinkOnly(absl::LogSink* absl_nonnull sink); |
122 | | |
123 | | // Don't call this method from outside this library. |
124 | 0 | LogMessage& InternalStream() { return *this; } |
125 | | |
126 | | // By-value overloads for small, common types let us overlook common failures |
127 | | // to define globals and static data members (i.e. in a .cc file). |
128 | | // NOLINTBEGIN(runtime/int) |
129 | | // NOLINTBEGIN(google-runtime-int) |
130 | | // clang-format off: The CUDA toolchain cannot handle these <<<'s |
131 | 0 | LogMessage& operator<<(char v) { return operator<< <char>(v); } |
132 | 0 | LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); } |
133 | 0 | LogMessage& operator<<(unsigned char v) { |
134 | 0 | return operator<< <unsigned char>(v); |
135 | 0 | } |
136 | 0 | LogMessage& operator<<(signed short v) { |
137 | 0 | return operator<< <signed short>(v); |
138 | 0 | } |
139 | 0 | LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); } |
140 | 0 | LogMessage& operator<<(signed long v) { |
141 | 0 | return operator<< <signed long>(v); |
142 | 0 | } |
143 | 0 | LogMessage& operator<<(signed long long v) { |
144 | 0 | return operator<< <signed long long>(v); |
145 | 0 | } |
146 | 0 | LogMessage& operator<<(unsigned short v) { |
147 | 0 | return operator<< <unsigned short>(v); |
148 | 0 | } |
149 | 0 | LogMessage& operator<<(unsigned int v) { |
150 | 0 | return operator<< <unsigned int>(v); |
151 | 0 | } |
152 | 0 | LogMessage& operator<<(unsigned long v) { |
153 | 0 | return operator<< <unsigned long>(v); |
154 | 0 | } |
155 | 0 | LogMessage& operator<<(unsigned long long v) { |
156 | 0 | return operator<< <unsigned long long>(v); |
157 | 0 | } |
158 | 0 | LogMessage& operator<<(void* absl_nullable v) { |
159 | 0 | return operator<< <void*>(v); |
160 | 0 | } |
161 | 0 | LogMessage& operator<<(const void* absl_nullable v) { |
162 | 0 | return operator<< <const void*>(v); |
163 | 0 | } |
164 | 0 | LogMessage& operator<<(float v) { return operator<< <float>(v); } |
165 | 0 | LogMessage& operator<<(double v) { return operator<< <double>(v); } |
166 | 0 | LogMessage& operator<<(bool v) { return operator<< <bool>(v); } |
167 | | // clang-format on |
168 | | // NOLINTEND(google-runtime-int) |
169 | | // NOLINTEND(runtime/int) |
170 | | |
171 | | // These overloads are more efficient since no `ostream` is involved. |
172 | | LogMessage& operator<<(const std::string& v); |
173 | | LogMessage& operator<<(absl::string_view v); |
174 | | |
175 | | // Wide string overloads (since std::ostream does not provide them). |
176 | | LogMessage& operator<<(const std::wstring& v); |
177 | | LogMessage& operator<<(std::wstring_view v); |
178 | | // `const wchar_t*` is handled by `operator<< <const wchar_t*>`. |
179 | | LogMessage& operator<<(wchar_t* absl_nullable v); |
180 | | LogMessage& operator<<(wchar_t v); |
181 | | |
182 | | // Handle stream manipulators e.g. std::endl. |
183 | | LogMessage& operator<<(std::ostream& (*absl_nonnull m)(std::ostream& os)); |
184 | | LogMessage& operator<<(std::ios_base& (*absl_nonnull m)(std::ios_base& os)); |
185 | | |
186 | | // Literal strings. This allows us to record C string literals as literals in |
187 | | // the logging.proto.Value. |
188 | | // |
189 | | // Allow this overload to be inlined to prevent generating instantiations of |
190 | | // this template for every value of `SIZE` encountered in each source code |
191 | | // file. That significantly increases linker input sizes. Inlining is cheap |
192 | | // because the argument to this overload is almost always a string literal so |
193 | | // the call to `strlen` can be replaced at compile time. The overloads for |
194 | | // `char[]`/`wchar_t[]` below should not be inlined. The compiler typically |
195 | | // does not have the string at compile time and cannot replace the call to |
196 | | // `strlen` so inlining it increases the binary size. See the discussion on |
197 | | // cl/107527369. |
198 | | template <int SIZE> |
199 | | LogMessage& operator<<(const char (&buf)[SIZE]); |
200 | | template <int SIZE> |
201 | | LogMessage& operator<<(const wchar_t (&buf)[SIZE]); |
202 | | |
203 | | // This prevents non-const `char[]` arrays from looking like literals. |
204 | | template <int SIZE> |
205 | | LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE; |
206 | | // `wchar_t[SIZE]` is handled by `operator<< <const wchar_t*>`. |
207 | | |
208 | | // Types that support `AbslStringify()` are serialized that way. |
209 | | // Types that don't support `AbslStringify()` but do support streaming into a |
210 | | // `std::ostream&` are serialized that way. |
211 | | template <typename T> |
212 | | LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE; |
213 | | |
214 | | // Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s. |
215 | | void Flush(); |
216 | | |
217 | | // Note: We explicitly do not support `operator<<` for non-const references |
218 | | // because it breaks logging of non-integer bitfield types (i.e., enums). |
219 | | |
220 | | protected: |
221 | | // Call `abort()` or similar to perform `LOG(FATAL)` crash. It is assumed |
222 | | // that the caller has already generated and written the trace as appropriate. |
223 | | [[noreturn]] static void FailWithoutStackTrace(); |
224 | | |
225 | | // Similar to `FailWithoutStackTrace()`, but without `abort()`. Terminates |
226 | | // the process with an error exit code. |
227 | | [[noreturn]] static void FailQuietly(); |
228 | | |
229 | | // After this is called, failures are done as quiet as possible for this log |
230 | | // message. |
231 | | void SetFailQuietly(); |
232 | | |
233 | | private: |
234 | | struct LogMessageData; // Opaque type containing message state |
235 | | friend class AsLiteralImpl; |
236 | | friend class StringifySink; |
237 | | template <StructuredStringType str_type> |
238 | | friend class AsStructuredStringTypeImpl; |
239 | | template <typename T> |
240 | | friend class AsStructuredValueImpl; |
241 | | |
242 | | // This streambuf writes directly into the structured logging buffer so that |
243 | | // arbitrary types can be encoded as string data (using |
244 | | // `operator<<(std::ostream &, ...)` without any extra allocation or copying. |
245 | | // Space is reserved before the data to store the length field, which is |
246 | | // filled in by `~OstreamView`. |
247 | | class OstreamView final : public std::streambuf { |
248 | | public: |
249 | | explicit OstreamView(LogMessageData& message_data); |
250 | | ~OstreamView() override; |
251 | | OstreamView(const OstreamView&) = delete; |
252 | | OstreamView& operator=(const OstreamView&) = delete; |
253 | | std::ostream& stream(); |
254 | | |
255 | | private: |
256 | | LogMessageData& data_; |
257 | | absl::Span<char> encoded_remaining_copy_; |
258 | | absl::Span<char> message_start_; |
259 | | absl::Span<char> string_start_; |
260 | | }; |
261 | | |
262 | | enum class StringType { |
263 | | kLiteral, |
264 | | kNotLiteral, |
265 | | }; |
266 | | template <StringType str_type> |
267 | | void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE; |
268 | | template <StringType str_type> |
269 | | void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE; |
270 | | template <StringType str_type> |
271 | | void CopyToEncodedBuffer(std::wstring_view str) ABSL_ATTRIBUTE_NOINLINE; |
272 | | |
273 | | // Copies `field` to the encoded buffer, then appends `str` after it |
274 | | // (truncating `str` if necessary to fit). |
275 | | template <StringType str_type> |
276 | | void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field, |
277 | | absl::string_view str) |
278 | | ABSL_ATTRIBUTE_NOINLINE; |
279 | | |
280 | | // Returns `true` if the message is fatal or enabled debug-fatal. |
281 | | bool IsFatal() const; |
282 | | |
283 | | // Records some tombstone-type data in anticipation of `Die`. |
284 | | void PrepareToDie(); |
285 | | void Die(); |
286 | | |
287 | | void SendToLog(); |
288 | | |
289 | | // Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate. |
290 | | void LogBacktraceIfNeeded(); |
291 | | |
292 | | // This should be the first data member so that its initializer captures errno |
293 | | // before any other initializers alter it (e.g. with calls to new) and so that |
294 | | // no other destructors run afterward an alter it (e.g. with calls to delete). |
295 | | absl::base_internal::ErrnoSaver errno_saver_; |
296 | | |
297 | | // We keep the data in a separate struct so that each instance of `LogMessage` |
298 | | // uses less stack space. |
299 | | absl_nonnull std::unique_ptr<LogMessageData> data_; |
300 | | }; |
301 | | |
302 | | // Explicitly specializes the generic operator<< for `const wchar_t*` |
303 | | // arguments. |
304 | | // |
305 | | // This method is used instead of a non-template `const wchar_t*` overload, |
306 | | // as the latter was found to take precedence over the array template |
307 | | // (`operator<<(const wchar_t(&)[SIZE])`) when handling string literals. |
308 | | // This specialization ensures the array template now correctly processes |
309 | | // literals. |
310 | | template <> |
311 | | LogMessage& LogMessage::operator<< <const wchar_t*>( |
312 | | const wchar_t* absl_nullable const& v); |
313 | | |
314 | 0 | inline LogMessage& LogMessage::operator<<(wchar_t* absl_nullable v) { |
315 | 0 | return operator<<(const_cast<const wchar_t*>(v)); |
316 | 0 | } |
317 | | |
318 | | // Helper class so that `AbslStringify()` can modify the LogMessage. |
319 | | class StringifySink final { |
320 | | public: |
321 | 0 | explicit StringifySink(LogMessage& message) : message_(message) {} |
322 | | |
323 | 0 | void Append(size_t count, char ch) { |
324 | 0 | message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch, |
325 | 0 | count); |
326 | 0 | } |
327 | | |
328 | 0 | void Append(absl::string_view v) { |
329 | 0 | message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v); |
330 | 0 | } |
331 | | |
332 | | // For types that implement `AbslStringify` using `absl::Format()`. |
333 | | friend void AbslFormatFlush(StringifySink* absl_nonnull sink, |
334 | 0 | absl::string_view v) { |
335 | 0 | sink->Append(v); |
336 | 0 | } |
337 | | |
338 | | private: |
339 | | LogMessage& message_; |
340 | | }; |
341 | | |
342 | | // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE` |
343 | | template <typename T> |
344 | 0 | LogMessage& LogMessage::operator<<(const T& v) { |
345 | | if constexpr (absl::HasAbslStringify<T>::value) { |
346 | | StringifySink sink(*this); |
347 | | // Replace with public API. |
348 | | AbslStringify(sink, v); |
349 | 0 | } else { |
350 | 0 | OstreamView view(*data_); |
351 | 0 | view.stream() << log_internal::NullGuard<T>().Guard(v); |
352 | 0 | } |
353 | 0 | return *this; |
354 | 0 | } Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <char>(char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <signed char>(signed char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned char>(unsigned char const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <short>(short const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned short>(unsigned short const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <int>(int const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned int>(unsigned int const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <long>(long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned long>(unsigned long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <long long>(long long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <unsigned long long>(unsigned long long const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <void*>(void* const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <void const*>(void const* const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <float>(float const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <double>(double const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <bool>(bool const&) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <char const*>(char const* const&) |
355 | | |
356 | | template <int SIZE> |
357 | 0 | LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) { |
358 | 0 | CopyToEncodedBuffer<StringType::kLiteral>(buf); |
359 | 0 | return *this; |
360 | 0 | } Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <3>(char const (&) [3]) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <2>(char const (&) [2]) Unexecuted instantiation: absl::log_internal::LogMessage& absl::log_internal::LogMessage::operator<< <15>(char const (&) [15]) |
361 | | |
362 | | template <int SIZE> |
363 | | LogMessage& LogMessage::operator<<(const wchar_t (&buf)[SIZE]) { |
364 | | CopyToEncodedBuffer<StringType::kLiteral>(buf); |
365 | | return *this; |
366 | | } |
367 | | |
368 | | // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE` |
369 | | template <int SIZE> |
370 | | LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) { |
371 | | CopyToEncodedBuffer<StringType::kNotLiteral>(buf); |
372 | | return *this; |
373 | | } |
374 | | // We instantiate these specializations in the library's TU to save space in |
375 | | // other TUs. Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be |
376 | | // emitting a function call either way. |
377 | | // NOLINTBEGIN(runtime/int) |
378 | | // NOLINTBEGIN(google-runtime-int) |
379 | | extern template LogMessage& LogMessage::operator<<(const char& v); |
380 | | extern template LogMessage& LogMessage::operator<<(const signed char& v); |
381 | | extern template LogMessage& LogMessage::operator<<(const unsigned char& v); |
382 | | extern template LogMessage& LogMessage::operator<<(const short& v); |
383 | | extern template LogMessage& LogMessage::operator<<(const unsigned short& v); |
384 | | extern template LogMessage& LogMessage::operator<<(const int& v); |
385 | | extern template LogMessage& LogMessage::operator<<(const unsigned int& v); |
386 | | extern template LogMessage& LogMessage::operator<<(const long& v); |
387 | | extern template LogMessage& LogMessage::operator<<(const unsigned long& v); |
388 | | extern template LogMessage& LogMessage::operator<<(const long long& v); |
389 | | extern template LogMessage& LogMessage::operator<<(const unsigned long long& v); |
390 | | extern template LogMessage& LogMessage::operator<<( |
391 | | void* absl_nullable const& v); |
392 | | extern template LogMessage& LogMessage::operator<<( |
393 | | const void* absl_nullable const& v); |
394 | | extern template LogMessage& LogMessage::operator<<(const float& v); |
395 | | extern template LogMessage& LogMessage::operator<<(const double& v); |
396 | | extern template LogMessage& LogMessage::operator<<(const bool& v); |
397 | | // NOLINTEND(google-runtime-int) |
398 | | // NOLINTEND(runtime/int) |
399 | | |
400 | | extern template void LogMessage::CopyToEncodedBuffer< |
401 | | LogMessage::StringType::kLiteral>(absl::string_view str); |
402 | | extern template void LogMessage::CopyToEncodedBuffer< |
403 | | LogMessage::StringType::kNotLiteral>(absl::string_view str); |
404 | | extern template void |
405 | | LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch, |
406 | | size_t num); |
407 | | extern template void LogMessage::CopyToEncodedBuffer< |
408 | | LogMessage::StringType::kNotLiteral>(char ch, size_t num); |
409 | | extern template void LogMessage::CopyToEncodedBuffer< |
410 | | LogMessage::StringType::kLiteral>(std::wstring_view str); |
411 | | extern template void LogMessage::CopyToEncodedBuffer< |
412 | | LogMessage::StringType::kNotLiteral>(std::wstring_view str); |
413 | | |
414 | | // `LogMessageFatal` ensures the process will exit in failure after logging this |
415 | | // message. |
416 | | class LogMessageFatal final : public LogMessage { |
417 | | public: |
418 | | LogMessageFatal(const char* absl_nonnull file, int line) ABSL_ATTRIBUTE_COLD; |
419 | | LogMessageFatal(const char* absl_nonnull file, int line, |
420 | | const char* absl_nonnull failure_msg) ABSL_ATTRIBUTE_COLD; |
421 | | [[noreturn]] ~LogMessageFatal(); |
422 | | }; |
423 | | |
424 | | // `LogMessageDebugFatal` ensures the process will exit in failure after logging |
425 | | // this message. It matches LogMessageFatal but is not [[noreturn]] as it's used |
426 | | // for DLOG(FATAL) variants. |
427 | | class LogMessageDebugFatal final : public LogMessage { |
428 | | public: |
429 | | LogMessageDebugFatal(const char* absl_nonnull file, |
430 | | int line) ABSL_ATTRIBUTE_COLD; |
431 | | ~LogMessageDebugFatal(); |
432 | | }; |
433 | | |
434 | | class LogMessageQuietlyDebugFatal final : public LogMessage { |
435 | | public: |
436 | | // DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the |
437 | | // destructor is not [[noreturn]] even if this is always FATAL as this is only |
438 | | // invoked when DLOG() is enabled. |
439 | | LogMessageQuietlyDebugFatal(const char* absl_nonnull file, |
440 | | int line) ABSL_ATTRIBUTE_COLD; |
441 | | ~LogMessageQuietlyDebugFatal(); |
442 | | }; |
443 | | |
444 | | // Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]]. |
445 | | class LogMessageQuietlyFatal final : public LogMessage { |
446 | | public: |
447 | | LogMessageQuietlyFatal(const char* absl_nonnull file, |
448 | | int line) ABSL_ATTRIBUTE_COLD; |
449 | | LogMessageQuietlyFatal(const char* absl_nonnull file, int line, |
450 | | const char* absl_nonnull failure_msg) |
451 | | ABSL_ATTRIBUTE_COLD; |
452 | | [[noreturn]] ~LogMessageQuietlyFatal(); |
453 | | }; |
454 | | |
455 | | } // namespace log_internal |
456 | | ABSL_NAMESPACE_END |
457 | | } // namespace absl |
458 | | |
459 | | extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( |
460 | | AbslInternalOnFatalLogMessage)(const absl::LogEntry&); |
461 | | |
462 | | #endif // ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |