00001 /* -*- mode:C++; c-basic-offset:4 -*- 00002 Shore-MT -- Multi-threaded port of the SHORE storage manager 00003 00004 Copyright (c) 2007-2009 00005 Data Intensive Applications and Systems Labaratory (DIAS) 00006 Ecole Polytechnique Federale de Lausanne 00007 00008 All Rights Reserved. 00009 00010 Permission to use, copy, modify and distribute this software and 00011 its documentation is hereby granted, provided that both the 00012 copyright notice and this permission notice appear in all copies of 00013 the software, derivative works or modified versions, and any 00014 portions thereof, and that both notices appear in supporting 00015 documentation. 00016 00017 This code is distributed in the hope that it will be useful, but 00018 WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS 00020 DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER 00021 RESULTING FROM THE USE OF THIS SOFTWARE. 00022 */ 00023 00024 /*<std-header orig-src='shore' incl-file-exclusion='W_WORKAROUND_H'> 00025 00026 $Id: w_workaround.h,v 1.61 2010/12/08 17:37:37 nhall Exp $ 00027 00028 SHORE -- Scalable Heterogeneous Object REpository 00029 00030 Copyright (c) 1994-99 Computer Sciences Department, University of 00031 Wisconsin -- Madison 00032 All Rights Reserved. 00033 00034 Permission to use, copy, modify and distribute this software and its 00035 documentation is hereby granted, provided that both the copyright 00036 notice and this permission notice appear in all copies of the 00037 software, derivative works or modified versions, and any portions 00038 thereof, and that both notices appear in supporting documentation. 00039 00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY 00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS 00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND 00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 00044 00045 This software was developed with support by the Advanced Research 00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by 00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518. 00048 Further funding for this work was provided by DARPA through 00049 Rome Research Laboratory Contract No. F30602-97-2-0247. 00050 00051 */ 00052 00053 #ifndef W_WORKAROUND_H 00054 #define W_WORKAROUND_H 00055 00056 #include "w_defines.h" 00057 00058 /* -- do not edit anything above this line -- </std-header>*/ 00059 00060 /**\file w_workaround.h 00061 * Macros that allow workarounds for different compilers. 00062 */ 00063 00064 00065 #ifdef __GNUC__ 00066 00067 /* Mechanism to make disjoint gcc numbering appear linear for comparison 00068 purposes. Without this all the Shore gcc hacks break when a new major 00069 number is encountered. 00070 */ 00071 00072 #define W_GCC_VER(major,minor) (((major) << 16) + (minor)) 00073 00074 #ifndef __GNUC_MINOR__ /* gcc-1.something -- No minor version number */ 00075 #define W_GCC_THIS_VER W_GCC_VER(__GNUC__,0) 00076 #else 00077 #define W_GCC_THIS_VER W_GCC_VER(__GNUC__,__GNUC_MINOR__) 00078 #endif 00079 00080 00081 #if W_GCC_THIS_VER < W_GCC_VER(2,5) 00082 /* XXX all the following tests assume this filter is used */ 00083 #error This software requires gcc 2.5.x or a later release. 00084 #error Gcc 2.6.0 is preferred. 00085 #endif 00086 00087 00088 #if W_GCC_THIS_VER < W_GCC_VER(2,6) 00089 00090 /* 00091 * G++ also has a bug in calling the destructor of a template 00092 */ 00093 # define GNUG_BUG_2 1 00094 00095 /* 00096 * G++ seems to have a problem calling ::operator delete 00097 */ 00098 # define GNUG_BUG_3 1 00099 00100 /* 00101 * G++ version 2.4.5 has problems with templates that don't have 00102 * destructors explicitly defined. It also seems to have problems 00103 * with classes used to instantiate templates if those classes 00104 * do not have destructors. 00105 */ 00106 # define GNUG_BUG_7 1 00107 00108 /* bug #8: 00109 * gcc include files don't define signal() as in ANSI C. 00110 * we need to get around that 00111 */ 00112 # define GNUG_BUG_8 1 00113 00114 #endif /* gcc < 2.6 */ 00115 00116 /* 00117 * #12 00118 * This is a bug in parsing specific to gcc 2.6.0. 00119 * The compiler misinterprets: 00120 * int(j) 00121 * to be a declaration of j as an int rather than the correct 00122 * interpretation as a cast of j to an int. This shows up in 00123 * statements like: 00124 * istrstream(c) >> i; 00125 */ 00126 00127 /* see below for more info on GNUG_BUG_12 */ 00128 #define GNUG_BUG_12(arg) arg 00129 #if W_GCC_THIS_VER > W_GCC_VER(2,5) 00130 # undef GNUG_BUG_12 00131 # define GNUG_BUG_12(arg) (arg) 00132 #endif 00133 00134 #if W_GCC_THIS_VER > W_GCC_VER(2,5) 00135 /* 00136 * GNU 2.6.0 : template functions that are 00137 * not member functions don't get exported from the 00138 * implementation file. 00139 */ 00140 #define GNUG_BUG_13 1 00141 00142 /* 00143 * Cannot explicitly instantiate function templates. 00144 */ 00145 #define GNUG_BUG_14 1 00146 #endif 00147 00148 #if W_GCC_THIS_VER > W_GCC_VER(2,6) 00149 /* gcc 2.7.2 has bogus warning messages; it doesn't inherit pointer 00150 properties correctly */ 00151 #define GNUG_BUG_15 1 00152 #endif 00153 00154 /* Gcc 64 bit integer math incorrectly optimizes range comparisons such as 00155 if (i64 < X || i64 > Y) 00156 zzz; 00157 This should be re-examined when we upgrade to 2.8, perhaps it is fixed and 00158 we can make this a 2.7 dependency. 00159 */ 00160 #define GNUG_BUG_16 00161 00162 /****************************************************************************** 00163 * 00164 * Migration to standard C++ 00165 * 00166 ******************************************************************************/ 00167 #if W_GCC_THIS_VER >= W_GCC_VER(2,90) 00168 /* 00169 * EGCS is 2.90 (which really screws up any attempt to fix 00170 * things based on __GNUC_MINOR__ and __GNUC__ 00171 * and egcs does not define any different macro to identify itself. 00172 */ 00173 #endif 00174 00175 #if W_GCC_THIS_VER < W_GCC_VER(2,8) 00176 00177 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) /**/ 00178 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3,TYP2,TMPLa,TMPLc,TMPLb) /**/ 00179 # define BIND_FRIEND_OPERATOR_PART_2(TYP) /**/ 00180 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,TYP2) /**/ 00181 00182 # else 00183 00184 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) \ 00185 template <class TYP, class L> \ 00186 ostream & operator<<(ostream&o, const TMPLa,TMPLb& l); 00187 00188 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3, TYP2,TMPLa,TMPLc,TMPLb) \ 00189 template <class TYP1, class TYP3, class TYP2> \ 00190 ostream & operator<<(ostream&o, const TMPLa,TMPLc,TMPLb& l); 00191 00192 # define BIND_FRIEND_OPERATOR_PART_2(TYP, L)\ 00193 <TYP, L> 00194 00195 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,L,TYP2)\ 00196 <TYP1, L, TYP2> 00197 00198 # endif 00199 00200 /* XXX 00201 * The gcc-3.x object model has changes which allow THIS to change 00202 * based upon inheritance and such. That isn't a problem. However, 00203 * they added a poor warning which breaks ANY use of offsetof(), even 00204 * legitimate cases where it is THE ONLY way to get the correct result and 00205 * where the result would be correct with the new model. This offsetof 00206 * implementation is designed to avoid that particular compiler warning. 00207 * Until the GCC guys admit they are doing something dumb, we need to do this. 00208 * 00209 * This could arguably belong in w_base.h, I put it here since w_base.h 00210 * always sucks this in and it is a compiler-dependency. 00211 */ 00212 #if W_GCC_THIS_VER >= W_GCC_VER(3,0) 00213 #define w_offsetof(t,f) \ 00214 ((size_t)((char*)&(*(t*)sizeof(t)).f - (char *)&(*(t*)sizeof(t)))) 00215 #endif 00216 00217 #endif /* __GNUC__ */ 00218 00219 #ifdef __SUNPRO_CC 00220 # define BIND_FRIEND_OPERATOR_PART_1(TYP,L,TMPLa,TMPLb) \ 00221 template <class TYP, class L> \ 00222 ostream & operator<<(ostream&o, const TMPLa,TMPLb& l); 00223 00224 # define BIND_FRIEND_OPERATOR_PART_1B(TYP1,TYP3, TYP2,TMPLa,TMPLc,TMPLb) \ 00225 template <class TYP1, class TYP3, class TYP2> \ 00226 ostream & operator<<(ostream&o, const TMPLa,TMPLc,TMPLb& l); 00227 00228 # define BIND_FRIEND_OPERATOR_PART_2(TYP,L)\ 00229 <TYP,L> 00230 00231 # define BIND_FRIEND_OPERATOR_PART_2B(TYP1,L,TYP2)\ 00232 <TYP1,L,TYP2> 00233 #endif 00234 /****************************************************************************** 00235 * 00236 * gcc complains about big literals which don't have the LL suffix. 00237 * don't know if egcs or gcc 2.95 have this problem, but it shouldn't hurt. 00238 * 00239 ******************************************************************************/ 00240 #ifdef __GNUC__ 00241 #define INT64_LITERAL_BUG(x) x ## LL 00242 #else 00243 #define INT64_LITERAL_BUG(x) x 00244 #endif 00245 00246 /****************************************************************************** 00247 * 00248 * C string bug 00249 * 00250 ******************************************************************************/ 00251 00252 /* 00253 * a C string constant is of type (const char*). some routines assume that 00254 * they are (char*). this is to cast away the const in those cases. 00255 */ 00256 #define C_STRING_BUG (char *) 00257 00258 00259 00260 /* This is really a library problem; stream.form() and stream.scan() 00261 aren't standard, but GNUisms. On the other hand, they should 00262 be in the standard, because they save us from static form() buffers. 00263 Using the W_FORM() and W_FORM2() macros instead of 00264 stream.form() or stream << form() encapsulates this use, so the 00265 optimal solution can be used on each platform. 00266 If a portable scan() equivalent is written, a similar set 00267 of W_SCAN macros could encapuslate input scanning too. 00268 */ 00269 #if defined(__GNUG__) 00270 #if W_GCC_THIS_VER < W_GCC_VER(3,0) 00271 #define FC_IOSTREAM_FORM_METHOD 00272 #else 00273 #define FC_NEED_UNBOUND_FORM 00274 #endif 00275 #elif defined(__SUNPRO_CC) 00276 #define FC_NEED_UNBOUND_FORM 00277 #endif 00278 00279 #ifdef FC_IOSTREAM_FORM_METHOD 00280 #define W_FORM(stream) stream . form 00281 #else 00282 #define W_FORM(stream) stream << form 00283 #endif 00284 00285 /* Grab our form if needed. */ 00286 #ifdef FC_NEED_UNBOUND_FORM 00287 // in w_form.cpp 00288 extern const char *form(const char *, ...); 00289 #endif 00290 00291 #define W_FORM2(stream,args) W_FORM(stream) args 00292 00293 /* 00294 * Try to use the system definition of offsetof, and provide one here 00295 * if the system's isn't in the standard place. 00296 */ 00297 #ifndef offsetof 00298 #include <cstddef> 00299 #endif 00300 #ifndef offsetof 00301 #define offsetof(type,member) ((size_t)((&(type *)0)->member)) 00302 #endif 00303 00304 #ifndef w_offsetof 00305 /* FRJ: Sun's CC returns an address near the top of the stack when 00306 given ``offsetof(a, b.c())'', where c() returns a reference to a 00307 private member of b. This seems to work around the issue (bug?). 00308 OLD: 00309 //template<class T> 00310 //static T* get_null() { return NULL; } 00311 //#define w_offsetof(class,member) ((size_t) &get_null<class>()->member) 00312 NEW: below 00313 */ 00314 #define w_offsetof(class,member) offsetof(class,member) 00315 #endif 00316 00317 /*<std-footer incl-file-exclusion='W_WORKAROUND_H'> -- do not edit anything below this line -- */ 00318 00319 #endif /*</std-footer>*/