/[pcsx2_0.9.7]/trunk/common/include/Utilities/Assertions.h
ViewVC logotype

Contents of /trunk/common/include/Utilities/Assertions.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 8230 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #ifndef __pxFUNCTION__
19 #if defined(__GNUG__)
20 # define __pxFUNCTION__ __PRETTY_FUNCTION__
21 #else
22 # define __pxFUNCTION__ __FUNCTION__
23 #endif
24 #endif
25
26 #ifndef wxNullChar
27 # define wxNullChar ((wxChar*)NULL)
28 #endif
29
30 // FnChar_t - function name char type; typedef'd in case it ever changes between compilers
31 // (ie, a compiler decides to wchar_t it instead of char/UTF8).
32 typedef char FnChar_t;
33
34 // --------------------------------------------------------------------------------------
35 // DiagnosticOrigin
36 // --------------------------------------------------------------------------------------
37 struct DiagnosticOrigin
38 {
39 const wxChar* srcfile;
40 const FnChar_t* function;
41 const wxChar* condition;
42 int line;
43
44 DiagnosticOrigin( const wxChar *_file, int _line, const FnChar_t *_func, const wxChar* _cond = NULL )
45 : srcfile( _file )
46 , function( _func )
47 , condition( _cond )
48 , line( _line )
49 {
50 }
51
52 wxString ToString( const wxChar* msg=NULL ) const;
53 };
54
55 // Returns ture if the assertion is to trap into the debugger, or false if execution
56 // of the program should continue unimpeded.
57 typedef bool pxDoAssertFnType(const DiagnosticOrigin& origin, const wxChar *msg);
58
59 extern pxDoAssertFnType pxAssertImpl_LogIt;
60
61 extern pxDoAssertFnType* pxDoAssert;
62
63 // ----------------------------------------------------------------------------------------
64 // pxAssert / pxAssertDev
65 // ----------------------------------------------------------------------------------------
66 // Standard "nothrow" assertions. All assertions act as valid conditional statements that
67 // return the result of the specified conditional; useful for handling failed assertions in
68 // a "graceful" fashion when utilizing the "ignore" feature of assertion debugging.
69 // These macros are mostly intended for "pseudo-weak" assumptions within code, most often for
70 // testing threaded user interface code (threading of the UI is a prime example since often
71 // even very robust assertions can fail in very rare conditions, due to the complex variety
72 // of ways the user can invoke UI events).
73 //
74 // All macros return TRUE if the assertion succeeds, or FALSE if the assertion failed
75 // (thus matching the condition of the assertion itself).
76 //
77 // pxAssertDev is an assertion tool for Devel builds, intended for sanity checking and/or
78 // bounds checking variables in areas which are not performance critical. Another common
79 // use is for checking thread affinity on utility functions.
80 //
81 // Credits: These macros are based on a combination of wxASSERT, MSVCRT's assert and the
82 // ATL's Assertion/Assumption macros. the best of all worlds!
83
84 // --------------------------------------------------------------------------------------
85 // pxAssume / pxAssumeDev / pxFail / pxFailDev
86 // --------------------------------------------------------------------------------------
87 // Assumptions are like "extra rigid" assertions, which should never fail under any circum-
88 // stance in release build optimized code.
89 //
90 // Performance: All assumption/fail types optimize into __assume()/likely() directives in
91 // Release builds (non-dev varieties optimize as such in Devel builds as well). If using
92 //
93 // Having pxFail and pxFailDev translate into __assume statements is very dangerous, since
94 // it can lead to the compiler optimizing out code and leading to crashes in dev/release
95 // builds. To have code optimized, explicitly use pxAssume(false) or pxAssumeDev(false,msg);
96
97 #define pxDiagSpot DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__ )
98 #define pxAssertSpot(cond) DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__, _T(#cond) )
99
100 // pxAssertRel ->
101 // Special release-mode assertion. Limited use since stack traces in release mode builds
102 // (especially with LTCG) are highly suspect. But when troubleshooting crashes that only
103 // rear ugly heads in optimized builds, this is one of the few tools we have.
104
105 #define pxAssertRel(cond, msg) ( (likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false) )
106 #define pxAssumeRel(cond, msg) ((void) ( (!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false) ))
107 #define pxFailRel(msg) pxAssertRel(false, msg)
108
109 #if defined(PCSX2_DEBUG)
110
111 # define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
112 # define pxAssertDev(cond, msg) pxAssertMsg(cond, msg)
113
114 # define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg)
115 # define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
116
117 # define pxFail(msg) pxAssertMsg(false, msg)
118 # define pxFailDev(msg) pxAssertDev(false, msg)
119
120 #elif defined(PCSX2_DEVBUILD)
121
122 // Devel builds use __assume for standard assertions and call pxOnAssertDevel
123 // for AssertDev brand assertions (which typically throws a LogicError exception).
124
125 # define pxAssertMsg(cond, msg) (likely(cond))
126 # define pxAssertDev(cond, msg) pxAssertRel(cond, msg)
127
128 # define pxAssumeMsg(cond, msg) (__assume(cond))
129 # define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
130
131 # define pxFail(msg)
132 # define pxFailDev(msg) pxAssertDev(false, msg)
133
134 #else
135
136 // Release Builds just use __assume as an optimization, and return the conditional
137 // as a result (which is optimized to nil if unused).
138
139 # define pxAssertMsg(cond, msg) (likely(cond))
140 # define pxAssertDev(cond, msg) (likely(cond))
141
142 # define pxAssumeMsg(cond, msg) (__assume(cond))
143 # define pxAssumeDev(cond, msg) (__assume(cond))
144
145 # define pxFail(msg)
146 # define pxFailDev(msg)
147
148 #endif
149
150 #define pxAssert(cond) pxAssertMsg(cond, wxNullChar)
151 #define pxAssume(cond) pxAssumeMsg(cond, wxNullChar)
152
153 #define pxAssertRelease( cond, msg )
154
155 // Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
156 // For stricter checking in Devel builds as well as debug builds (but possibly slower), use
157 // IndexBoundsCheckDev.
158
159 #define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \
160 wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
161
162 #define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \
163 wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
164
165 #define IndexBoundsAssume( objname, idx, sze ) pxAssumeMsg( (uint)(idx) < (uint)(sze), \
166 wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
167
168 #define IndexBoundsAssumeDev( objname, idx, sze ) pxAssumeDev( (uint)(idx) < (uint)(sze), \
169 wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
170
171
172 extern void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg=NULL );
173 extern void pxOnAssert( const DiagnosticOrigin& origin, const char* msg );
174
175 // --------------------------------------------------------------------------------------
176 // jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
177 // under MSVC.
178 // --------------------------------------------------------------------------------------
179 // How it Works: pxAssumeDev turns into an __assume(0) under msvc compilers, which when specified
180 // in the 'default:' case of a switch tells the compiler that the case is unreachable, so
181 // that it will not generate any code, LUTs, or conditionals to handle it.
182 //
183 // * In debug/devel builds the default case will cause an assertion.
184 //
185 #ifndef jNO_DEFAULT
186 # define jNO_DEFAULT \
187 default: \
188 { \
189 pxAssumeDev( false, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \
190 break; \
191 }
192 #endif

  ViewVC Help
Powered by ViewVC 1.1.22