xref: /aosp_15_r20/external/angle/src/common/log_utils.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // log_utils.h: Logging and assert utilities. A lot of the logging code is adapted from Chromium's
8*8975f5c5SAndroid Build Coastguard Worker // base/logging.h.
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_LOG_UTILS_H_
11*8975f5c5SAndroid Build Coastguard Worker #define COMMON_LOG_UTILS_H_
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include <assert.h>
14*8975f5c5SAndroid Build Coastguard Worker #include <stdio.h>
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include <iomanip>
17*8975f5c5SAndroid Build Coastguard Worker #include <ios>
18*8975f5c5SAndroid Build Coastguard Worker #include <mutex>
19*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
20*8975f5c5SAndroid Build Coastguard Worker #include <string>
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "common/entry_points_enum_autogen.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "common/platform.h"
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker namespace gl
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker class Context;
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker using LogSeverity = int;
31*8975f5c5SAndroid Build Coastguard Worker // Note: the log severities are used to index into the array of names,
32*8975f5c5SAndroid Build Coastguard Worker // see g_logSeverityNames.
33*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_EVENT          = 0;
34*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_INFO           = 1;
35*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_WARN           = 2;
36*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_ERR            = 3;
37*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_FATAL          = 4;
38*8975f5c5SAndroid Build Coastguard Worker constexpr LogSeverity LOG_NUM_SEVERITIES = 5;
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker void Trace(LogSeverity severity, const char *message);
41*8975f5c5SAndroid Build Coastguard Worker 
42*8975f5c5SAndroid Build Coastguard Worker // This class more or less represents a particular log message.  You
43*8975f5c5SAndroid Build Coastguard Worker // create an instance of LogMessage and then stream stuff to it.
44*8975f5c5SAndroid Build Coastguard Worker // When you finish streaming to it, ~LogMessage is called and the
45*8975f5c5SAndroid Build Coastguard Worker // full message gets streamed to the appropriate destination.
46*8975f5c5SAndroid Build Coastguard Worker //
47*8975f5c5SAndroid Build Coastguard Worker // You shouldn't actually use LogMessage's constructor to log things,
48*8975f5c5SAndroid Build Coastguard Worker // though.  You should use the ERR() and WARN() macros.
49*8975f5c5SAndroid Build Coastguard Worker class LogMessage : angle::NonCopyable
50*8975f5c5SAndroid Build Coastguard Worker {
51*8975f5c5SAndroid Build Coastguard Worker   public:
52*8975f5c5SAndroid Build Coastguard Worker     // Used for ANGLE_LOG(severity).
53*8975f5c5SAndroid Build Coastguard Worker     LogMessage(const char *file, const char *function, int line, LogSeverity severity);
54*8975f5c5SAndroid Build Coastguard Worker     ~LogMessage();
stream()55*8975f5c5SAndroid Build Coastguard Worker     std::ostream &stream() { return mStream; }
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     LogSeverity getSeverity() const;
58*8975f5c5SAndroid Build Coastguard Worker     std::string getMessage() const;
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker   private:
61*8975f5c5SAndroid Build Coastguard Worker     const char *mFile;
62*8975f5c5SAndroid Build Coastguard Worker     const char *mFunction;
63*8975f5c5SAndroid Build Coastguard Worker     const int mLine;
64*8975f5c5SAndroid Build Coastguard Worker     const LogSeverity mSeverity;
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream mStream;
67*8975f5c5SAndroid Build Coastguard Worker };
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker bool ShouldBeginScopedEvent(const gl::Context *context);
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker namespace priv
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker // This class is used to explicitly ignore values in the conditional logging macros. This avoids
74*8975f5c5SAndroid Build Coastguard Worker // compiler warnings like "value computed is not used" and "statement has no effect".
75*8975f5c5SAndroid Build Coastguard Worker class LogMessageVoidify
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker   public:
LogMessageVoidify()78*8975f5c5SAndroid Build Coastguard Worker     LogMessageVoidify() {}
79*8975f5c5SAndroid Build Coastguard Worker     // This has to be an operator with a precedence lower than << but higher than ?:
80*8975f5c5SAndroid Build Coastguard Worker     void operator&(std::ostream &) {}
81*8975f5c5SAndroid Build Coastguard Worker };
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker extern std::ostream *gSwallowStream;
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker // Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments.
86*8975f5c5SAndroid Build Coastguard Worker bool ShouldCreatePlatformLogMessage(LogSeverity severity);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker // N is the width of the output to the stream. The output is padded with zeros
89*8975f5c5SAndroid Build Coastguard Worker // if value is less than N characters.
90*8975f5c5SAndroid Build Coastguard Worker // S is the stream type, either ostream for ANSI or wostream for wide character.
91*8975f5c5SAndroid Build Coastguard Worker // T is the type of the value to output to the stream.
92*8975f5c5SAndroid Build Coastguard Worker // C is the type of characters - either char for ANSI or wchar_t for wide char.
93*8975f5c5SAndroid Build Coastguard Worker template <int N, typename S, typename T, typename C>
FmtHex(S & stream,T value,const C * zeroX,C zero)94*8975f5c5SAndroid Build Coastguard Worker S &FmtHex(S &stream, T value, const C *zeroX, C zero)
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker     stream << zeroX;
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker     std::ios_base::fmtflags oldFlags = stream.flags();
99*8975f5c5SAndroid Build Coastguard Worker     std::streamsize oldWidth         = stream.width();
100*8975f5c5SAndroid Build Coastguard Worker     typename S::char_type oldFill    = stream.fill();
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     stream << std::hex << std::uppercase << std::setw(N) << std::setfill(zero) << value;
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker     stream.flags(oldFlags);
105*8975f5c5SAndroid Build Coastguard Worker     stream.width(oldWidth);
106*8975f5c5SAndroid Build Coastguard Worker     stream.fill(oldFill);
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     return stream;
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker template <typename S, typename T, typename C>
FmtHexAutoSized(S & stream,T value,const C * prefix,const C * zeroX,C zero)112*8975f5c5SAndroid Build Coastguard Worker S &FmtHexAutoSized(S &stream, T value, const C *prefix, const C *zeroX, C zero)
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker     if (prefix)
115*8975f5c5SAndroid Build Coastguard Worker     {
116*8975f5c5SAndroid Build Coastguard Worker         stream << prefix;
117*8975f5c5SAndroid Build Coastguard Worker     }
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     constexpr int N = sizeof(T) * 2;
120*8975f5c5SAndroid Build Coastguard Worker     return priv::FmtHex<N>(stream, value, zeroX, zero);
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker template <typename T, typename C>
124*8975f5c5SAndroid Build Coastguard Worker class FmtHexHelper
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker   public:
FmtHexHelper(const C * prefix,T value)127*8975f5c5SAndroid Build Coastguard Worker     FmtHexHelper(const C *prefix, T value) : mPrefix(prefix), mValue(value) {}
FmtHexHelper(T value)128*8975f5c5SAndroid Build Coastguard Worker     explicit FmtHexHelper(T value) : mPrefix(nullptr), mValue(value) {}
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker   private:
131*8975f5c5SAndroid Build Coastguard Worker     const C *mPrefix;
132*8975f5c5SAndroid Build Coastguard Worker     T mValue;
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker     friend std::ostream &operator<<(std::ostream &os, const FmtHexHelper &fmt)
135*8975f5c5SAndroid Build Coastguard Worker     {
136*8975f5c5SAndroid Build Coastguard Worker         return FmtHexAutoSized(os, fmt.mValue, fmt.mPrefix, "0x", '0');
137*8975f5c5SAndroid Build Coastguard Worker     }
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker     friend std::wostream &operator<<(std::wostream &wos, const FmtHexHelper &fmt)
140*8975f5c5SAndroid Build Coastguard Worker     {
141*8975f5c5SAndroid Build Coastguard Worker         return FmtHexAutoSized(wos, fmt.mValue, fmt.mPrefix, L"0x", L'0');
142*8975f5c5SAndroid Build Coastguard Worker     }
143*8975f5c5SAndroid Build Coastguard Worker };
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker }  // namespace priv
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker template <typename T, typename C = char>
FmtHex(T value)148*8975f5c5SAndroid Build Coastguard Worker priv::FmtHexHelper<T, C> FmtHex(T value)
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker     return priv::FmtHexHelper<T, C>(value);
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_WINDOWS)
154*8975f5c5SAndroid Build Coastguard Worker priv::FmtHexHelper<HRESULT, char> FmtHR(HRESULT value);
155*8975f5c5SAndroid Build Coastguard Worker priv::FmtHexHelper<DWORD, char> FmtErr(DWORD value);
156*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_PLATFORM_WINDOWS)
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker template <typename T>
FmtHex(std::ostream & os,T value)159*8975f5c5SAndroid Build Coastguard Worker std::ostream &FmtHex(std::ostream &os, T value)
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker     return priv::FmtHexAutoSized(os, value, "", "0x", '0');
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker // A few definitions of macros that don't generate much code. These are used
165*8975f5c5SAndroid Build Coastguard Worker // by ANGLE_LOG(). Since these are used all over our code, it's
166*8975f5c5SAndroid Build Coastguard Worker // better to have compact code for these operations.
167*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \
168*8975f5c5SAndroid Build Coastguard Worker     ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__)
169*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EX_INFO(ClassName, ...) \
170*8975f5c5SAndroid Build Coastguard Worker     ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_INFO, ##__VA_ARGS__)
171*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \
172*8975f5c5SAndroid Build Coastguard Worker     ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__)
173*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \
174*8975f5c5SAndroid Build Coastguard Worker     ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__)
175*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EX_FATAL(ClassName, ...) \
176*8975f5c5SAndroid Build Coastguard Worker     ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_FATAL, ##__VA_ARGS__)
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage)
179*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_INFO COMPACT_ANGLE_LOG_EX_INFO(LogMessage)
180*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage)
181*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage)
182*8975f5c5SAndroid Build Coastguard Worker #define COMPACT_ANGLE_LOG_FATAL COMPACT_ANGLE_LOG_EX_FATAL(LogMessage)
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_##severity))
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker // Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
187*8975f5c5SAndroid Build Coastguard Worker // Condition is evaluated once and only once.
188*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_LAZY_STREAM(stream, condition) \
189*8975f5c5SAndroid Build Coastguard Worker     !(condition) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (stream)
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker // We use the preprocessor's merging operator, "##", so that, e.g.,
192*8975f5c5SAndroid Build Coastguard Worker // ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT.  There's some funny
193*8975f5c5SAndroid Build Coastguard Worker // subtle difference between ostream member streaming functions (e.g.,
194*8975f5c5SAndroid Build Coastguard Worker // ostream::operator<<(int) and ostream non-member streaming functions
195*8975f5c5SAndroid Build Coastguard Worker // (e.g., ::operator<<(ostream&, string&): it turns out that it's
196*8975f5c5SAndroid Build Coastguard Worker // impossible to stream something like a string directly to an unnamed
197*8975f5c5SAndroid Build Coastguard Worker // ostream. We employ a neat hack by calling the stream() member
198*8975f5c5SAndroid Build Coastguard Worker // function of LogMessage which seems to avoid the problem.
199*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream()
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity))
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
206*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_TRACE_ENABLED
207*8975f5c5SAndroid Build Coastguard Worker #endif
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(ANGLE_ASSERT_ALWAYS_ON)
210*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_ENABLE_ASSERTS
211*8975f5c5SAndroid Build Coastguard Worker #endif
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker #define INFO() ANGLE_LOG(INFO)
214*8975f5c5SAndroid Build Coastguard Worker #define WARN() ANGLE_LOG(WARN)
215*8975f5c5SAndroid Build Coastguard Worker #define ERR() ANGLE_LOG(ERR)
216*8975f5c5SAndroid Build Coastguard Worker #define FATAL() ANGLE_LOG(FATAL)
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker // A macro to log a performance event around a scope.
219*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_TRACE_ENABLED)
220*8975f5c5SAndroid Build Coastguard Worker #    if defined(_MSC_VER)
221*8975f5c5SAndroid Build Coastguard Worker #        define EVENT(context, entryPoint, message, ...)                                     \
222*8975f5c5SAndroid Build Coastguard Worker             gl::ScopedPerfEventHelper scopedPerfEventHelper##__LINE__(                       \
223*8975f5c5SAndroid Build Coastguard Worker                 context, angle::EntryPoint::entryPoint);                                     \
224*8975f5c5SAndroid Build Coastguard Worker             do                                                                               \
225*8975f5c5SAndroid Build Coastguard Worker             {                                                                                \
226*8975f5c5SAndroid Build Coastguard Worker                 if (gl::ShouldBeginScopedEvent(context))                                     \
227*8975f5c5SAndroid Build Coastguard Worker                 {                                                                            \
228*8975f5c5SAndroid Build Coastguard Worker                     scopedPerfEventHelper##__LINE__.begin(                                   \
229*8975f5c5SAndroid Build Coastguard Worker                         "%s(" message ")", GetEntryPointName(angle::EntryPoint::entryPoint), \
230*8975f5c5SAndroid Build Coastguard Worker                         __VA_ARGS__);                                                        \
231*8975f5c5SAndroid Build Coastguard Worker                 }                                                                            \
232*8975f5c5SAndroid Build Coastguard Worker             } while (0)
233*8975f5c5SAndroid Build Coastguard Worker #    else
234*8975f5c5SAndroid Build Coastguard Worker #        define EVENT(context, entryPoint, message, ...)                                          \
235*8975f5c5SAndroid Build Coastguard Worker             gl::ScopedPerfEventHelper scopedPerfEventHelper(context,                              \
236*8975f5c5SAndroid Build Coastguard Worker                                                             angle::EntryPoint::entryPoint);       \
237*8975f5c5SAndroid Build Coastguard Worker             do                                                                                    \
238*8975f5c5SAndroid Build Coastguard Worker             {                                                                                     \
239*8975f5c5SAndroid Build Coastguard Worker                 if (gl::ShouldBeginScopedEvent(context))                                          \
240*8975f5c5SAndroid Build Coastguard Worker                 {                                                                                 \
241*8975f5c5SAndroid Build Coastguard Worker                     scopedPerfEventHelper.begin("%s(" message ")",                                \
242*8975f5c5SAndroid Build Coastguard Worker                                                 GetEntryPointName(angle::EntryPoint::entryPoint), \
243*8975f5c5SAndroid Build Coastguard Worker                                                 ##__VA_ARGS__);                                   \
244*8975f5c5SAndroid Build Coastguard Worker                 }                                                                                 \
245*8975f5c5SAndroid Build Coastguard Worker             } while (0)
246*8975f5c5SAndroid Build Coastguard Worker #    endif  // _MSC_VER
247*8975f5c5SAndroid Build Coastguard Worker #else
248*8975f5c5SAndroid Build Coastguard Worker #    define EVENT(message, ...) (void(0))
249*8975f5c5SAndroid Build Coastguard Worker #endif
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker // Note that gSwallowStream is used instead of an arbitrary LOG() stream to avoid the creation of an
252*8975f5c5SAndroid Build Coastguard Worker // object with a non-trivial destructor (LogMessage). On MSVC x86 (checked on 2015 Update 3), this
253*8975f5c5SAndroid Build Coastguard Worker // causes a few additional pointless instructions to be emitted even at full optimization level,
254*8975f5c5SAndroid Build Coastguard Worker // even though the : arm of the ternary operator is clearly never executed. Using a simpler object
255*8975f5c5SAndroid Build Coastguard Worker // to be &'d with Voidify() avoids these extra instructions. Using a simpler POD object with a
256*8975f5c5SAndroid Build Coastguard Worker // templated operator<< also works to avoid these instructions. However, this causes warnings on
257*8975f5c5SAndroid Build Coastguard Worker // statically defined implementations of operator<<(std::ostream, ...) in some .cpp files, because
258*8975f5c5SAndroid Build Coastguard Worker // they become defined-but-unreferenced functions. A reinterpret_cast of 0 to an ostream* also is
259*8975f5c5SAndroid Build Coastguard Worker // not suitable, because some compilers warn of undefined behavior.
260*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EAT_STREAM_PARAMETERS \
261*8975f5c5SAndroid Build Coastguard Worker     true ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (*::gl::priv::gSwallowStream)
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker // A macro asserting a condition and outputting failures to the debug log
264*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
265*8975f5c5SAndroid Build Coastguard Worker #    define ASSERT(expression)                                                                \
266*8975f5c5SAndroid Build Coastguard Worker         (expression ? static_cast<void>(0)                                                    \
267*8975f5c5SAndroid Build Coastguard Worker                     : (FATAL() << "\t! Assert failed in " << __FUNCTION__ << " (" << __FILE__ \
268*8975f5c5SAndroid Build Coastguard Worker                                << ":" << __LINE__ << "): " << #expression))
269*8975f5c5SAndroid Build Coastguard Worker #else
270*8975f5c5SAndroid Build Coastguard Worker #    define ASSERT(condition) ANGLE_EAT_STREAM_PARAMETERS << !(condition)
271*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_ASSERTS)
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker // A macro to indicate unimplemented functionality
274*8975f5c5SAndroid Build Coastguard Worker #ifndef NOASSERT_UNIMPLEMENTED
275*8975f5c5SAndroid Build Coastguard Worker #    define NOASSERT_UNIMPLEMENTED 1
276*8975f5c5SAndroid Build Coastguard Worker #endif
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
279*8975f5c5SAndroid Build Coastguard Worker #    define UNIMPLEMENTED()                                                                       \
280*8975f5c5SAndroid Build Coastguard Worker         do                                                                                        \
281*8975f5c5SAndroid Build Coastguard Worker         {                                                                                         \
282*8975f5c5SAndroid Build Coastguard Worker             WARN() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \
283*8975f5c5SAndroid Build Coastguard Worker                    << ")";                                                                        \
284*8975f5c5SAndroid Build Coastguard Worker             ASSERT(NOASSERT_UNIMPLEMENTED);                                                       \
285*8975f5c5SAndroid Build Coastguard Worker         } while (0)
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker // A macro for code which is not expected to be reached under valid assumptions
288*8975f5c5SAndroid Build Coastguard Worker #    define UNREACHABLE()                                                                    \
289*8975f5c5SAndroid Build Coastguard Worker         do                                                                                   \
290*8975f5c5SAndroid Build Coastguard Worker         {                                                                                    \
291*8975f5c5SAndroid Build Coastguard Worker             FATAL() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __FILE__ << ":" \
292*8975f5c5SAndroid Build Coastguard Worker                     << __LINE__ << ")";                                                      \
293*8975f5c5SAndroid Build Coastguard Worker         } while (0)
294*8975f5c5SAndroid Build Coastguard Worker #else
295*8975f5c5SAndroid Build Coastguard Worker #    define UNIMPLEMENTED()                 \
296*8975f5c5SAndroid Build Coastguard Worker         do                                  \
297*8975f5c5SAndroid Build Coastguard Worker         {                                   \
298*8975f5c5SAndroid Build Coastguard Worker             ASSERT(NOASSERT_UNIMPLEMENTED); \
299*8975f5c5SAndroid Build Coastguard Worker         } while (0)
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker // A macro for code which is not expected to be reached under valid assumptions
302*8975f5c5SAndroid Build Coastguard Worker #    define UNREACHABLE()  \
303*8975f5c5SAndroid Build Coastguard Worker         do                 \
304*8975f5c5SAndroid Build Coastguard Worker         {                  \
305*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false); \
306*8975f5c5SAndroid Build Coastguard Worker         } while (0)
307*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
308*8975f5c5SAndroid Build Coastguard Worker 
309*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_WINDOWS)
310*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_FUNCTION __FUNCTION__
311*8975f5c5SAndroid Build Coastguard Worker #else
312*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_FUNCTION __func__
313*8975f5c5SAndroid Build Coastguard Worker #endif
314*8975f5c5SAndroid Build Coastguard Worker 
315*8975f5c5SAndroid Build Coastguard Worker #endif  // COMMON_LOG_UTILS_H_
316