this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Made libunwind-darwin-gcc buildable

+16093 -25
+1
CMakeLists.txt
··· 91 91 92 92 add_subdirectory(src/libSystem) 93 93 add_subdirectory(src/libcxxdarwin) 94 + #add_subdirectory(src/libunwind-darwin-gcc) 94 95 add_subdirectory(src/libncurses) 95 96 #add_subdirectory(src/CoreServices) 96 97
+28 -9
src/libunwind-darwin-gcc/CMakeLists.txt
··· 1 - project(unwind-darwin) 1 + project(cxxdarwin) 2 2 3 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I./include -stdlib=libc++ -fPIC -gdwarf-2") 4 + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic -Wl,-Bsymbolic-functions -stdlib=libc++") 3 5 cmake_minimum_required(VERSION 2.4.0) 4 6 if(COMMAND cmake_policy) 5 7 cmake_policy(SET CMP0003 NEW) ··· 7 9 8 10 set (unwind_SRCS 9 11 # emutls.c 10 - unwind-c.c 11 - unwind-compat.c 12 - unwind-dw2-fde-darwin.c 13 - unwind-dw2-fde-compat.c 14 - unwind-dw2.c 15 - unwind-sjlj.c 12 + src-unwind/unwind-c.c 13 + src-unwind/unwind-compat.c 14 + src-unwind/unwind-dw2-fde-darwin.c 15 + src-unwind/unwind-dw2-fde-compat.c 16 + src-unwind/unwind-dw2.c 17 + src-unwind/darwin-crt2.c 18 + # src-unwind/unwind-sjlj.c 19 + ) 20 + 21 + set (abi_SRCS 22 + src-cxxabi/abort_message.cpp src-cxxabi/cxa_demangle.cpp 23 + src-cxxabi/cxa_guard.cpp src-cxxabi/cxa_personality.cpp 24 + src-cxxabi/cxa_virtual.cpp src-cxxabi/stdexcept.cpp 25 + src-cxxabi/cxa_aux_runtime.cpp 26 + src-cxxabi/cxa_exception.cpp src-cxxabi/cxa_handlers.cpp 27 + src-cxxabi/cxa_unexpected.cpp src-cxxabi/exception.cpp 28 + src-cxxabi/typeinfo.cpp 29 + src-cxxabi/cxa_default_handlers.cpp 30 + src-cxxabi/cxa_exception_storage.cpp 31 + src-cxxabi/cxa_new_delete.cpp 32 + src-cxxabi/cxa_vector.cpp 33 + src-cxxabi/private_typeinfo.cpp 16 34 ) 17 35 18 - add_library(unwind-darwin SHARED ${unwind_SRCS}) 36 + 37 + add_library(cxxdarwin SHARED ${unwind_SRCS} ${abi_SRCS}) 19 38 #target_link_libraries(unwind-darwin -Tlink.cmd) 20 - install(TARGETS unwind-darwin DESTINATION lib) 39 + install(TARGETS cxxdarwin DESTINATION lib${SUFFIX})
src/libunwind-darwin-gcc/coretypes.h src/libunwind-darwin-gcc/src-unwind/coretypes.h
src/libunwind-darwin-gcc/defaults.h src/libunwind-darwin-gcc/src-unwind/defaults.h
src/libunwind-darwin-gcc/dwarf2.h src/libunwind-darwin-gcc/src-unwind/dwarf2.h
src/libunwind-darwin-gcc/emutls.c src/libunwind-darwin-gcc/src-unwind/emutls.c
src/libunwind-darwin-gcc/gthr.h src/libunwind-darwin-gcc/src-unwind/gthr.h
-2
src/libunwind-darwin-gcc/link.cmd
··· 1 - __darwin_Unwind_RaiseException = _Unwind_RaiseException ; 2 -
src/libunwind-darwin-gcc/mcore.h src/libunwind-darwin-gcc/src-unwind/mcore.h
+50
src/libunwind-darwin-gcc/src-cxxabi/abort_message.cpp
··· 1 + //===------------------------- abort_message.cpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include <stdlib.h> 11 + #include <stdio.h> 12 + #include <stdarg.h> 13 + #include "abort_message.h" 14 + 15 + #pragma GCC visibility push(hidden) 16 + 17 + #if __APPLE__ 18 + # if defined(__has_include) && __has_include(<CrashReporterClient.h>) 19 + # define HAVE_CRASHREPORTERCLIENT_H 1 20 + # include <CrashReporterClient.h> 21 + # endif 22 + #endif 23 + 24 + __attribute__((visibility("hidden"), noreturn)) 25 + void abort_message(const char* format, ...) 26 + { 27 + // write message to stderr 28 + #if __APPLE__ 29 + fprintf(stderr, "libc++abi.dylib: "); 30 + #endif 31 + va_list list; 32 + va_start(list, format); 33 + vfprintf(stderr, format, list); 34 + va_end(list); 35 + fprintf(stderr, "\n"); 36 + 37 + #if __APPLE__ && HAVE_CRASHREPORTERCLIENT_H 38 + // record message in crash report 39 + char* buffer; 40 + va_list list2; 41 + va_start(list2, format); 42 + vasprintf(&buffer, format, list2); 43 + va_end(list2); 44 + CRSetCrashLogMessage(buffer); 45 + #endif 46 + 47 + abort(); 48 + } 49 + 50 + #pragma GCC visibility pop
+33
src/libunwind-darwin-gcc/src-cxxabi/abort_message.h
··· 1 + //===-------------------------- abort_message.h-----------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #ifndef __ABORT_MESSAGE_H_ 11 + #define __ABORT_MESSAGE_H_ 12 + 13 + #include <stdio.h> 14 + 15 + #pragma GCC visibility push(hidden) 16 + 17 + #ifdef __cplusplus 18 + extern "C" { 19 + #endif 20 + 21 + __attribute__((visibility("hidden"), noreturn)) 22 + void abort_message(const char* format, ...) 23 + __attribute__((format(printf, 1, 2))); 24 + 25 + 26 + #ifdef __cplusplus 27 + } 28 + #endif 29 + 30 + #pragma GCC visibility pop 31 + 32 + #endif 33 +
+34
src/libunwind-darwin-gcc/src-cxxabi/cxa_aux_runtime.cpp
··· 1 + //===------------------------ cxa_aux_runtime.cpp -------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Auxiliary Runtime APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html#cxx-aux 11 + //===----------------------------------------------------------------------===// 12 + 13 + #include "cxxabi.h" 14 + #include <typeinfo> 15 + 16 + namespace __cxxabiv1 17 + { 18 + 19 + extern "C" 20 + { 21 + 22 + LIBCXXABI_NORETURN 23 + void __cxa_bad_cast (void) { 24 + throw std::bad_cast(); 25 + } 26 + 27 + LIBCXXABI_NORETURN 28 + void __cxa_bad_typeid(void) { 29 + throw std::bad_typeid(); 30 + } 31 + 32 + } // extern "C" 33 + 34 + } // abi
+124
src/libunwind-darwin-gcc/src-cxxabi/cxa_default_handlers.cpp
··· 1 + //===------------------------- cxa_default_handlers.cpp -------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the default terminate_handler and unexpected_handler. 10 + //===----------------------------------------------------------------------===// 11 + 12 + #include <stdexcept> 13 + #include <new> 14 + #include <exception> 15 + #include "abort_message.h" 16 + #include "cxxabi.h" 17 + #include "cxa_handlers.hpp" 18 + #include "cxa_exception.hpp" 19 + #include "private_typeinfo.h" 20 + 21 + __attribute__((noreturn)) 22 + static void default_handler(const char* cause) 23 + { 24 + // If there might be an uncaught exception 25 + using namespace __cxxabiv1; 26 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); 27 + if (globals) 28 + { 29 + __cxa_exception* exception_header = globals->caughtExceptions; 30 + // If there is an uncaught exception 31 + if (exception_header) 32 + { 33 + _Unwind_Exception* unwind_exception = 34 + reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 35 + bool native_exception = 36 + (unwind_exception->exception_class & get_vendor_and_language) == 37 + (kOurExceptionClass & get_vendor_and_language); 38 + if (native_exception) 39 + { 40 + void* thrown_object = 41 + unwind_exception->exception_class == kOurDependentExceptionClass ? 42 + ((__cxa_dependent_exception*)exception_header)->primaryException : 43 + exception_header + 1; 44 + const __shim_type_info* thrown_type = 45 + static_cast<const __shim_type_info*>(exception_header->exceptionType); 46 + // Try to get demangled name of thrown_type 47 + int status; 48 + char buf[1024]; 49 + size_t len = sizeof(buf); 50 + const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); 51 + if (status != 0) 52 + name = thrown_type->name(); 53 + // If the uncaught exception can be caught with std::exception& 54 + const __shim_type_info* catch_type = 55 + static_cast<const __shim_type_info*>(&typeid(std::exception)); 56 + if (catch_type->can_catch(thrown_type, thrown_object)) 57 + { 58 + // Include the what() message from the exception 59 + const std::exception* e = static_cast<const std::exception*>(thrown_object); 60 + abort_message("terminating with %s exception of type %s: %s", 61 + cause, name, e->what()); 62 + } 63 + else 64 + // Else just note that we're terminating with an exception 65 + abort_message("terminating with %s exception of type %s", 66 + cause, name); 67 + } 68 + else 69 + // Else we're terminating with a foreign exception 70 + abort_message("terminating with %s foreign exception", cause); 71 + } 72 + } 73 + // Else just note that we're terminating 74 + abort_message("terminating"); 75 + } 76 + 77 + 78 + __attribute__((noreturn)) 79 + static void default_terminate_handler() 80 + { 81 + default_handler("uncaught"); 82 + } 83 + 84 + __attribute__((noreturn)) 85 + static void default_unexpected_handler() 86 + { 87 + default_handler("unexpected"); 88 + } 89 + 90 + 91 + // 92 + // Global variables that hold the pointers to the current handler 93 + // 94 + std::terminate_handler __cxa_terminate_handler = default_terminate_handler; 95 + std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler; 96 + 97 + // In the future these will become: 98 + // std::atomic<std::terminate_handler> __cxa_terminate_handler(default_terminate_handler); 99 + // std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler); 100 + 101 + namespace std 102 + { 103 + 104 + unexpected_handler 105 + set_unexpected(unexpected_handler func) _NOEXCEPT 106 + { 107 + if (func == 0) 108 + func = default_unexpected_handler; 109 + return __sync_swap(&__cxa_unexpected_handler, func); 110 + // Using of C++11 atomics this should be rewritten 111 + // return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel); 112 + } 113 + 114 + terminate_handler 115 + set_terminate(terminate_handler func) _NOEXCEPT 116 + { 117 + if (func == 0) 118 + func = default_terminate_handler; 119 + return __sync_swap(&__cxa_terminate_handler, func); 120 + // Using of C++11 atomics this should be rewritten 121 + // return __cxa_terminate_handler.exchange(func, memory_order_acq_rel); 122 + } 123 + 124 + }
+11011
src/libunwind-darwin-gcc/src-cxxabi/cxa_demangle.cpp
··· 1 + //===-------------------------- cxa_demangle.cpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include "cxa_demangle.h" 11 + 12 + #include <stdlib.h> 13 + #include <string.h> 14 + #include <ctype.h> 15 + #include <stdio.h> 16 + #include <new> 17 + #include <algorithm> 18 + #include <assert.h> 19 + 20 + #ifdef DEBUGGING 21 + 22 + #include <string> 23 + #include <typeinfo> 24 + 25 + #endif 26 + 27 + namespace __cxxabiv1 28 + { 29 + 30 + namespace __libcxxabi 31 + { 32 + 33 + #pragma GCC visibility push(hidden) 34 + 35 + class __node 36 + { 37 + __node(const __node&); 38 + __node& operator=(const __node&); 39 + public: 40 + const char* __name_; 41 + size_t __size_; 42 + __node* __left_; 43 + __node* __right_; 44 + long __cached_size_; 45 + long double __value_; 46 + public: 47 + __node() 48 + : __name_(0), __size_(0), __left_(0), __right_(0), __cached_size_(-1) 49 + {} 50 + virtual ~__node() {}; 51 + 52 + void reset_cached_size() 53 + { 54 + __cached_size_ = -1; 55 + if (__left_) 56 + __left_->reset_cached_size(); 57 + if (__right_) 58 + __right_->reset_cached_size(); 59 + } 60 + 61 + virtual size_t first_size() const {return 0;} 62 + virtual size_t second_size() const {return 0;} 63 + virtual size_t size() const 64 + { 65 + if (__cached_size_ == -1) 66 + const_cast<long&>(__cached_size_) = static_cast<long>(first_size() + second_size()); 67 + return static_cast<size_t>(__cached_size_); 68 + } 69 + virtual char* first_demangled_name(char* buf) const {return buf;} 70 + virtual char* second_demangled_name(char* buf) const {return buf;} 71 + virtual char* get_demangled_name(char* buf) const 72 + { 73 + return second_demangled_name(first_demangled_name(buf)); 74 + } 75 + virtual size_t base_size() const {return size();} 76 + virtual char* get_base_name(char* buf) const 77 + { 78 + return get_demangled_name(buf); 79 + } 80 + 81 + virtual bool ends_with_template(bool /*parsing*/ = false) const 82 + { 83 + return false; 84 + } 85 + virtual bool is_ctor_dtor_conv() const 86 + { 87 + return false; 88 + } 89 + virtual __node* base_name() const 90 + { 91 + return const_cast<__node*>(this); 92 + } 93 + virtual bool is_reference_or_pointer_to_function_or_array() const 94 + { 95 + return false; 96 + } 97 + virtual bool is_function() const 98 + { 99 + return false; 100 + } 101 + virtual bool is_cv_qualifer() const 102 + { 103 + return false; 104 + } 105 + virtual bool is_array() const 106 + { 107 + return false; 108 + } 109 + 110 + virtual bool fix_forward_references(__node**, __node**) 111 + { 112 + return true; 113 + } 114 + virtual __node* extract_cv(__node*&) const 115 + { 116 + return 0; 117 + } 118 + virtual size_t list_len() const 119 + { 120 + return 0; 121 + } 122 + virtual bool is_sub() const 123 + { 124 + return false; 125 + } 126 + }; 127 + 128 + #ifdef DEBUGGING 129 + 130 + void display(__node* x, int indent = 0) 131 + { 132 + if (x) 133 + { 134 + for (int i = 0; i < 2*indent; ++i) 135 + printf(" "); 136 + char* buf = (char*)malloc(x->size()); 137 + x->get_demangled_name(buf); 138 + printf("%s %s, %p\n", typeid(*x).name(), buf, x); 139 + free(buf); 140 + display(x->__left_, indent+1); 141 + display(x->__right_, indent+1); 142 + } 143 + } 144 + 145 + #endif 146 + 147 + class __vtable 148 + : public __node 149 + { 150 + static const ptrdiff_t n = sizeof("vtable for ") - 1; 151 + public: 152 + __vtable(__node* type) 153 + { 154 + __right_ = type; 155 + } 156 + 157 + virtual size_t first_size() const 158 + { 159 + if (__cached_size_ == -1) 160 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); 161 + return static_cast<size_t>(__cached_size_); 162 + } 163 + virtual char* first_demangled_name(char* buf) const 164 + { 165 + strncpy(buf, "vtable for ", n); 166 + return __right_->get_demangled_name(buf+n); 167 + } 168 + virtual __node* base_name() const 169 + { 170 + return __right_->base_name(); 171 + } 172 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 173 + { 174 + return __right_->fix_forward_references(t_begin, t_end); 175 + } 176 + }; 177 + 178 + class __VTT 179 + : public __node 180 + { 181 + static const ptrdiff_t n = sizeof("VTT for ") - 1; 182 + public: 183 + __VTT(__node* type) 184 + { 185 + __right_ = type; 186 + } 187 + 188 + virtual size_t first_size() const 189 + { 190 + if (__cached_size_ == -1) 191 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); 192 + return static_cast<size_t>(__cached_size_); 193 + } 194 + virtual char* first_demangled_name(char* buf) const 195 + { 196 + strncpy(buf, "VTT for ", n); 197 + return __right_->get_demangled_name(buf+n); 198 + } 199 + virtual __node* base_name() const 200 + { 201 + return __right_->base_name(); 202 + } 203 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 204 + { 205 + return __right_->fix_forward_references(t_begin, t_end); 206 + } 207 + }; 208 + 209 + class __construction_vtable 210 + : public __node 211 + { 212 + static const ptrdiff_t n = sizeof("construction vtable for ") - 1 + 4; 213 + public: 214 + __construction_vtable(__node* left, __node* right) 215 + { 216 + __left_ = left; 217 + __right_ = right; 218 + } 219 + 220 + virtual size_t first_size() const 221 + { 222 + if (__cached_size_ == -1) 223 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__left_->size() 224 + + __right_->size()); 225 + return static_cast<size_t>(__cached_size_); 226 + } 227 + virtual char* first_demangled_name(char* buf) const 228 + { 229 + strncpy(buf, "construction vtable for ", n-4); 230 + buf = __left_->get_demangled_name(buf+n-4); 231 + *buf++ = '-'; 232 + *buf++ = 'i'; 233 + *buf++ = 'n'; 234 + *buf++ = '-'; 235 + return __right_->get_demangled_name(buf); 236 + } 237 + virtual __node* base_name() const 238 + { 239 + return __right_->base_name(); 240 + } 241 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 242 + { 243 + bool r = true; 244 + if (__left_) 245 + r = __left_->fix_forward_references(t_begin, t_end); 246 + return r && __right_->fix_forward_references(t_begin, t_end); 247 + } 248 + }; 249 + 250 + class __typeinfo 251 + : public __node 252 + { 253 + static const ptrdiff_t n = sizeof("typeinfo for ") - 1; 254 + public: 255 + __typeinfo(__node* type) 256 + { 257 + __right_ = type; 258 + } 259 + 260 + virtual size_t first_size() const 261 + { 262 + if (__cached_size_ == -1) 263 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); 264 + return static_cast<size_t>(__cached_size_); 265 + } 266 + virtual char* first_demangled_name(char* buf) const 267 + { 268 + strncpy(buf, "typeinfo for ", n); 269 + return __right_->get_demangled_name(buf+n); 270 + } 271 + virtual __node* base_name() const 272 + { 273 + return __right_->base_name(); 274 + } 275 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 276 + { 277 + return __right_->fix_forward_references(t_begin, t_end); 278 + } 279 + }; 280 + 281 + class __typeinfo_name 282 + : public __node 283 + { 284 + static const ptrdiff_t n = sizeof("typeinfo name for ") - 1; 285 + public: 286 + __typeinfo_name(__node* type) 287 + { 288 + __right_ = type; 289 + } 290 + 291 + virtual size_t first_size() const 292 + { 293 + if (__cached_size_ == -1) 294 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); 295 + return static_cast<size_t>(__cached_size_); 296 + } 297 + virtual char* first_demangled_name(char* buf) const 298 + { 299 + strncpy(buf, "typeinfo name for ", n); 300 + return __right_->get_demangled_name(buf+n); 301 + } 302 + virtual __node* base_name() const 303 + { 304 + return __right_->base_name(); 305 + } 306 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 307 + { 308 + return __right_->fix_forward_references(t_begin, t_end); 309 + } 310 + }; 311 + 312 + class __covariant_return_thunk 313 + : public __node 314 + { 315 + static const ptrdiff_t n = sizeof("covariant return thunk to ") - 1; 316 + public: 317 + __covariant_return_thunk(__node* type) 318 + { 319 + __right_ = type; 320 + } 321 + 322 + virtual size_t first_size() const 323 + { 324 + if (__cached_size_ == -1) 325 + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); 326 + return static_cast<size_t>(__cached_size_); 327 + } 328 + virtual char* first_demangled_name(char* buf) const 329 + { 330 + strncpy(buf, "covariant return thunk to ", n); 331 + return __right_->get_demangled_name(buf+n); 332 + } 333 + virtual __node* base_name() const 334 + { 335 + return __right_->base_name(); 336 + } 337 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 338 + { 339 + return __right_->fix_forward_references(t_begin, t_end); 340 + } 341 + }; 342 + 343 + class __virtual_thunk 344 + : public __node 345 + { 346 + static const size_t n = sizeof("virtual thunk to ") - 1; 347 + public: 348 + __virtual_thunk(__node* type) 349 + { 350 + __right_ = type; 351 + } 352 + 353 + virtual size_t first_size() const 354 + { 355 + if (__cached_size_ == -1) 356 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); 357 + return static_cast<size_t>(__cached_size_); 358 + } 359 + virtual char* first_demangled_name(char* buf) const 360 + { 361 + strncpy(buf, "virtual thunk to ", n); 362 + return __right_->get_demangled_name(buf+n); 363 + } 364 + virtual __node* base_name() const 365 + { 366 + return __right_->base_name(); 367 + } 368 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 369 + { 370 + return __right_->fix_forward_references(t_begin, t_end); 371 + } 372 + }; 373 + 374 + class __non_virtual_thunk 375 + : public __node 376 + { 377 + static const size_t n = sizeof("non-virtual thunk to ") - 1; 378 + public: 379 + __non_virtual_thunk(__node* type) 380 + { 381 + __right_ = type; 382 + } 383 + 384 + virtual size_t first_size() const 385 + { 386 + if (__cached_size_ == -1) 387 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); 388 + return static_cast<size_t>(__cached_size_); 389 + } 390 + virtual char* first_demangled_name(char* buf) const 391 + { 392 + strncpy(buf, "non-virtual thunk to ", n); 393 + return __right_->get_demangled_name(buf+n); 394 + } 395 + virtual __node* base_name() const 396 + { 397 + return __right_->base_name(); 398 + } 399 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 400 + { 401 + return __right_->fix_forward_references(t_begin, t_end); 402 + } 403 + }; 404 + 405 + class __guard_variable 406 + : public __node 407 + { 408 + static const size_t n = sizeof("guard variable for ") - 1; 409 + public: 410 + __guard_variable(__node* type) 411 + { 412 + __right_ = type; 413 + } 414 + 415 + virtual size_t first_size() const 416 + { 417 + if (__cached_size_ == -1) 418 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); 419 + return static_cast<size_t>(__cached_size_); 420 + } 421 + virtual char* first_demangled_name(char* buf) const 422 + { 423 + strncpy(buf, "guard variable for ", n); 424 + return __right_->get_demangled_name(buf+n); 425 + } 426 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 427 + { 428 + return __right_->fix_forward_references(t_begin, t_end); 429 + } 430 + }; 431 + 432 + class __reference_temporary 433 + : public __node 434 + { 435 + static const size_t n = sizeof("reference temporary for ") - 1; 436 + public: 437 + __reference_temporary(__node* type) 438 + { 439 + __right_ = type; 440 + } 441 + 442 + virtual size_t first_size() const 443 + { 444 + if (__cached_size_ == -1) 445 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __right_->size()); 446 + return static_cast<size_t>(__cached_size_); 447 + } 448 + virtual char* first_demangled_name(char* buf) const 449 + { 450 + strncpy(buf, "reference temporary for ", n); 451 + return __right_->get_demangled_name(buf+n); 452 + } 453 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 454 + { 455 + return __right_->fix_forward_references(t_begin, t_end); 456 + } 457 + }; 458 + 459 + class __source_name 460 + : public __node 461 + { 462 + public: 463 + __source_name(const char* __name, size_t __size) 464 + { 465 + __name_ = __name; 466 + __size_ = __size; 467 + } 468 + 469 + virtual size_t first_size() const 470 + { 471 + if (__cached_size_ == -1) 472 + { 473 + if (__size_ >= 10 && strncmp(__name_, "_GLOBAL__N", 10) == 0) 474 + const_cast<long&>(__cached_size_) = 21; 475 + else 476 + const_cast<long&>(__cached_size_) = static_cast<long>(__size_); 477 + } 478 + return static_cast<size_t>(__cached_size_); 479 + } 480 + virtual char* first_demangled_name(char* buf) const 481 + { 482 + if (__size_ >= 10 && strncmp(__name_, "_GLOBAL__N", 10) == 0) 483 + return strncpy(buf, "(anonymous namespace)", 21) + 21; 484 + return strncpy(buf, __name_, __size_) + __size_; 485 + } 486 + }; 487 + 488 + class __operator_new 489 + : public __node 490 + { 491 + public: 492 + 493 + virtual size_t first_size() const {return sizeof("operator new") - 1;} 494 + virtual char* first_demangled_name(char* buf) const 495 + { 496 + return strncpy(buf, "operator new", sizeof("operator new") - 1) + 497 + sizeof("operator new") - 1; 498 + } 499 + }; 500 + 501 + class __operator_new_array 502 + : public __node 503 + { 504 + public: 505 + 506 + virtual size_t first_size() const {return sizeof("operator new[]") - 1;} 507 + virtual char* first_demangled_name(char* buf) const 508 + { 509 + return strncpy(buf, "operator new[]", sizeof("operator new[]") - 1) + 510 + sizeof("operator new[]") - 1; 511 + } 512 + }; 513 + 514 + class __operator_delete 515 + : public __node 516 + { 517 + public: 518 + 519 + virtual size_t first_size() const {return sizeof("operator delete") - 1;} 520 + virtual char* first_demangled_name(char* buf) const 521 + { 522 + return strncpy(buf, "operator delete", sizeof("operator delete") - 1) + 523 + sizeof("operator delete") - 1; 524 + } 525 + }; 526 + 527 + class __operator_delete_array 528 + : public __node 529 + { 530 + public: 531 + 532 + virtual size_t first_size() const {return sizeof("operator delete[]") - 1;} 533 + virtual char* first_demangled_name(char* buf) const 534 + { 535 + return strncpy(buf, "operator delete[]", sizeof("operator delete[]") - 1) + 536 + sizeof("operator delete[]") - 1; 537 + } 538 + }; 539 + 540 + class __operator_logical_and 541 + : public __node 542 + { 543 + public: 544 + 545 + __operator_logical_and() {} 546 + __operator_logical_and(__node* op1, __node* op2) 547 + { 548 + __left_ = op1; 549 + __right_ = op2; 550 + } 551 + virtual size_t first_size() const 552 + { 553 + if (__cached_size_ == -1) 554 + { 555 + if (__left_) 556 + const_cast<long&>(__cached_size_) = static_cast<long>( 557 + __left_->size() + 8 + 558 + __right_->size()); 559 + else 560 + const_cast<long&>(__cached_size_) = sizeof("operator&&") - 1; 561 + } 562 + return static_cast<size_t>(__cached_size_); 563 + } 564 + virtual char* first_demangled_name(char* buf) const 565 + { 566 + if (__left_) 567 + { 568 + *buf++ = '('; 569 + buf = __left_->get_demangled_name(buf); 570 + strncpy(buf, ") && (", 6); 571 + buf += 6; 572 + buf = __right_->get_demangled_name(buf); 573 + *buf++ = ')'; 574 + } 575 + else 576 + { 577 + strncpy(buf, "operator&&", sizeof("operator&&") - 1); 578 + buf += sizeof("operator&&") - 1; 579 + } 580 + return buf; 581 + } 582 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 583 + { 584 + bool r = true; 585 + if (__left_) 586 + r = r && __left_->fix_forward_references(t_begin, t_end); 587 + if (__right_) 588 + r = r && __right_->fix_forward_references(t_begin, t_end); 589 + return r; 590 + } 591 + }; 592 + 593 + class __operator_addressof 594 + : public __node 595 + { 596 + public: 597 + 598 + __operator_addressof() {} 599 + explicit __operator_addressof(__node* op) 600 + { 601 + __left_ = op; 602 + } 603 + virtual size_t first_size() const 604 + { 605 + if (__cached_size_ == -1) 606 + { 607 + if (__left_) 608 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 609 + else 610 + const_cast<long&>(__cached_size_) = sizeof("operator&") - 1; 611 + } 612 + return static_cast<size_t>(__cached_size_); 613 + } 614 + virtual char* first_demangled_name(char* buf) const 615 + { 616 + if (__left_) 617 + { 618 + *buf++ = '&'; 619 + *buf++ = '('; 620 + buf = __left_->get_demangled_name(buf); 621 + *buf++ = ')'; 622 + } 623 + else 624 + { 625 + strncpy(buf, "operator&", sizeof("operator&") - 1); 626 + buf += sizeof("operator&") - 1; 627 + } 628 + return buf; 629 + } 630 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 631 + { 632 + if (__left_) 633 + return __left_->fix_forward_references(t_begin, t_end); 634 + return true; 635 + } 636 + }; 637 + 638 + class __operator_bit_and 639 + : public __node 640 + { 641 + public: 642 + 643 + __operator_bit_and() {} 644 + __operator_bit_and(__node* op1, __node* op2) 645 + { 646 + __left_ = op1; 647 + __right_ = op2; 648 + } 649 + virtual size_t first_size() const 650 + { 651 + if (__cached_size_ == -1) 652 + { 653 + if (__left_) 654 + const_cast<long&>(__cached_size_) = static_cast<long>( 655 + __left_->size() + 7 + 656 + __right_->size()); 657 + else 658 + const_cast<long&>(__cached_size_) = sizeof("operator&") - 1; 659 + } 660 + return static_cast<size_t>(__cached_size_); 661 + } 662 + virtual char* first_demangled_name(char* buf) const 663 + { 664 + if (__left_) 665 + { 666 + *buf++ = '('; 667 + buf = __left_->get_demangled_name(buf); 668 + strncpy(buf, ") & (", 5); 669 + buf += 5; 670 + buf = __right_->get_demangled_name(buf); 671 + *buf++ = ')'; 672 + } 673 + else 674 + { 675 + strncpy(buf, "operator&", sizeof("operator&") - 1); 676 + buf += sizeof("operator&") - 1; 677 + } 678 + return buf; 679 + } 680 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 681 + { 682 + bool r = true; 683 + if (__left_) 684 + r = r && __left_->fix_forward_references(t_begin, t_end); 685 + if (__right_) 686 + r = r && __right_->fix_forward_references(t_begin, t_end); 687 + return r; 688 + } 689 + }; 690 + 691 + class __operator_and_equal 692 + : public __node 693 + { 694 + public: 695 + 696 + __operator_and_equal() {} 697 + __operator_and_equal(__node* op1, __node* op2) 698 + { 699 + __left_ = op1; 700 + __right_ = op2; 701 + } 702 + virtual size_t first_size() const 703 + { 704 + if (__cached_size_ == -1) 705 + { 706 + if (__left_) 707 + const_cast<long&>(__cached_size_) = static_cast<long>( 708 + __left_->size() + 8 + 709 + __right_->size()); 710 + else 711 + const_cast<long&>(__cached_size_) = sizeof("operator&=") - 1; 712 + } 713 + return static_cast<size_t>(__cached_size_); 714 + } 715 + virtual char* first_demangled_name(char* buf) const 716 + { 717 + if (__left_) 718 + { 719 + *buf++ = '('; 720 + buf = __left_->get_demangled_name(buf); 721 + strncpy(buf, ") &= (", 6); 722 + buf += 6; 723 + buf = __right_->get_demangled_name(buf); 724 + *buf++ = ')'; 725 + } 726 + else 727 + { 728 + strncpy(buf, "operator&=", sizeof("operator&=") - 1); 729 + buf += sizeof("operator&=") - 1; 730 + } 731 + return buf; 732 + } 733 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 734 + { 735 + bool r = true; 736 + if (__left_) 737 + r = r && __left_->fix_forward_references(t_begin, t_end); 738 + if (__right_) 739 + r = r && __right_->fix_forward_references(t_begin, t_end); 740 + return r; 741 + } 742 + }; 743 + 744 + class __operator_equal 745 + : public __node 746 + { 747 + public: 748 + 749 + __operator_equal() {} 750 + __operator_equal(__node* op1, __node* op2) 751 + { 752 + __left_ = op1; 753 + __right_ = op2; 754 + } 755 + virtual size_t first_size() const 756 + { 757 + if (__cached_size_ == -1) 758 + { 759 + if (__left_) 760 + const_cast<long&>(__cached_size_) = static_cast<long>( 761 + __left_->size() + 7 + 762 + __right_->size()); 763 + else 764 + const_cast<long&>(__cached_size_) = sizeof("operator=") - 1; 765 + } 766 + return static_cast<size_t>(__cached_size_); 767 + } 768 + virtual char* first_demangled_name(char* buf) const 769 + { 770 + if (__left_) 771 + { 772 + *buf++ = '('; 773 + buf = __left_->get_demangled_name(buf); 774 + strncpy(buf, ") = (", 5); 775 + buf += 5; 776 + buf = __right_->get_demangled_name(buf); 777 + *buf++ = ')'; 778 + } 779 + else 780 + { 781 + strncpy(buf, "operator=", sizeof("operator=") - 1); 782 + buf += sizeof("operator=") - 1; 783 + } 784 + return buf; 785 + } 786 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 787 + { 788 + bool r = true; 789 + if (__left_) 790 + r = r && __left_->fix_forward_references(t_begin, t_end); 791 + if (__right_) 792 + r = r && __right_->fix_forward_references(t_begin, t_end); 793 + return r; 794 + } 795 + }; 796 + 797 + class __operator_alignof_type 798 + : public __node 799 + { 800 + public: 801 + 802 + __operator_alignof_type() {} 803 + __operator_alignof_type(__node* op) 804 + { 805 + __right_ = op; 806 + } 807 + virtual size_t first_size() const 808 + { 809 + if (__cached_size_ == -1) 810 + { 811 + if (__right_) 812 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 10); 813 + else 814 + const_cast<long&>(__cached_size_) = sizeof("operator alignof") - 1; 815 + } 816 + return static_cast<size_t>(__cached_size_); 817 + } 818 + virtual char* first_demangled_name(char* buf) const 819 + { 820 + if (__right_) 821 + { 822 + strncpy(buf, "alignof (", 9); 823 + buf += 9; 824 + buf = __right_->get_demangled_name(buf); 825 + *buf++ = ')'; 826 + } 827 + else 828 + { 829 + strncpy(buf, "operator alignof", sizeof("operator alignof") - 1); 830 + buf += sizeof("operator alignof") - 1; 831 + } 832 + return buf; 833 + } 834 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 835 + { 836 + if (__right_) 837 + return __right_->fix_forward_references(t_begin, t_end); 838 + return true; 839 + } 840 + }; 841 + 842 + class __operator_alignof_expression 843 + : public __node 844 + { 845 + public: 846 + 847 + __operator_alignof_expression() {} 848 + __operator_alignof_expression(__node* op) 849 + { 850 + __right_ = op; 851 + } 852 + virtual size_t first_size() const 853 + { 854 + if (__cached_size_ == -1) 855 + { 856 + if (__right_) 857 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 10); 858 + else 859 + const_cast<long&>(__cached_size_) = sizeof("operator alignof") - 1; 860 + } 861 + return static_cast<size_t>(__cached_size_); 862 + } 863 + virtual char* first_demangled_name(char* buf) const 864 + { 865 + if (__right_) 866 + { 867 + strncpy(buf, "alignof (", 9); 868 + buf += 9; 869 + buf = __right_->get_demangled_name(buf); 870 + *buf++ = ')'; 871 + } 872 + else 873 + { 874 + strncpy(buf, "operator alignof", sizeof("operator alignof") - 1); 875 + buf += sizeof("operator alignof") - 1; 876 + } 877 + return buf; 878 + } 879 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 880 + { 881 + if (__right_) 882 + return __right_->fix_forward_references(t_begin, t_end); 883 + return true; 884 + } 885 + }; 886 + 887 + class __operator_paren 888 + : public __node 889 + { 890 + public: 891 + 892 + virtual size_t first_size() const {return sizeof("operator()") - 1;} 893 + virtual char* first_demangled_name(char* buf) const 894 + { 895 + strncpy(buf, "operator()", sizeof("operator()") - 1); 896 + return buf + sizeof("operator()") - 1; 897 + } 898 + }; 899 + 900 + class __operator_comma 901 + : public __node 902 + { 903 + public: 904 + 905 + __operator_comma() {} 906 + __operator_comma(__node* op1, __node* op2) 907 + { 908 + __left_ = op1; 909 + __right_ = op2; 910 + } 911 + virtual size_t first_size() const 912 + { 913 + if (__cached_size_ == -1) 914 + { 915 + if (__left_) 916 + const_cast<long&>(__cached_size_) = static_cast<long>( 917 + __left_->size() + 7 + 918 + __right_->size()); 919 + else 920 + const_cast<long&>(__cached_size_) = sizeof("operator,") - 1; 921 + } 922 + return static_cast<size_t>(__cached_size_); 923 + } 924 + virtual char* first_demangled_name(char* buf) const 925 + { 926 + if (__left_) 927 + { 928 + *buf++ = '('; 929 + buf = __left_->get_demangled_name(buf); 930 + strncpy(buf, ") , (", 5); 931 + buf += 5; 932 + buf = __right_->get_demangled_name(buf); 933 + *buf++ = ')'; 934 + } 935 + else 936 + { 937 + strncpy(buf, "operator,", sizeof("operator,") - 1); 938 + buf += sizeof("operator,") - 1; 939 + } 940 + return buf; 941 + } 942 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 943 + { 944 + bool r = true; 945 + if (__left_) 946 + r = r && __left_->fix_forward_references(t_begin, t_end); 947 + if (__right_) 948 + r = r && __right_->fix_forward_references(t_begin, t_end); 949 + return r; 950 + } 951 + }; 952 + 953 + class __operator_tilda 954 + : public __node 955 + { 956 + public: 957 + 958 + __operator_tilda() {} 959 + explicit __operator_tilda(__node* op) 960 + { 961 + __left_ = op; 962 + } 963 + virtual size_t first_size() const 964 + { 965 + if (__cached_size_ == -1) 966 + { 967 + if (__left_) 968 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 969 + else 970 + const_cast<long&>(__cached_size_) = sizeof("operator~") - 1; 971 + } 972 + return static_cast<size_t>(__cached_size_); 973 + } 974 + virtual char* first_demangled_name(char* buf) const 975 + { 976 + if (__left_) 977 + { 978 + *buf++ = '~'; 979 + *buf++ = '('; 980 + buf = __left_->get_demangled_name(buf); 981 + *buf++ = ')'; 982 + } 983 + else 984 + { 985 + strncpy(buf, "operator~", sizeof("operator~") - 1); 986 + buf += sizeof("operator~") - 1; 987 + } 988 + return buf; 989 + } 990 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 991 + { 992 + if (__left_) 993 + return __left_->fix_forward_references(t_begin, t_end); 994 + return true; 995 + } 996 + }; 997 + 998 + class __operator_cast 999 + : public __node 1000 + { 1001 + static const size_t n = sizeof("operator ") - 1; 1002 + public: 1003 + 1004 + explicit __operator_cast(__node* type) 1005 + { 1006 + __right_ = type; 1007 + } 1008 + __operator_cast(__node* type, __node* arg) 1009 + { 1010 + __size_ = 1; 1011 + __right_ = type; 1012 + __left_ = arg; 1013 + } 1014 + virtual size_t first_size() const 1015 + { 1016 + if (__cached_size_ == -1) 1017 + { 1018 + size_t off; 1019 + if (__size_) 1020 + { 1021 + off = 4; 1022 + off += __right_->size(); 1023 + if (__left_) 1024 + off += __left_->size(); 1025 + } 1026 + else 1027 + off = n + __right_->size();; 1028 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 1029 + } 1030 + return static_cast<size_t>(__cached_size_); 1031 + } 1032 + virtual char* first_demangled_name(char* buf) const 1033 + { 1034 + if (__size_) 1035 + { 1036 + *buf++ = '('; 1037 + buf = __right_->get_demangled_name(buf); 1038 + *buf++ = ')'; 1039 + *buf++ = '('; 1040 + if (__left_) 1041 + buf = __left_->get_demangled_name(buf); 1042 + *buf++ = ')'; 1043 + } 1044 + else 1045 + { 1046 + strncpy(buf, "operator ", n); 1047 + buf = __right_->get_demangled_name(buf+n); 1048 + } 1049 + return buf; 1050 + } 1051 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1052 + { 1053 + bool r = true; 1054 + if (__left_) 1055 + r = r && __left_->fix_forward_references(t_begin, t_end); 1056 + r = r && __right_->fix_forward_references(t_begin, t_end); 1057 + return r; 1058 + } 1059 + virtual bool is_ctor_dtor_conv() const 1060 + { 1061 + return true; 1062 + } 1063 + }; 1064 + 1065 + class __cast_literal 1066 + : public __node 1067 + { 1068 + public: 1069 + 1070 + __cast_literal(__node* type, const char* f, const char* l) 1071 + { 1072 + __left_ = type; 1073 + __name_ = f; 1074 + __size_ = static_cast<size_t>(l - f); 1075 + } 1076 + virtual size_t first_size() const 1077 + { 1078 + if (__cached_size_ == -1) 1079 + const_cast<long&>(__cached_size_) = static_cast<long>(2 + 1080 + __left_->size() + __size_); 1081 + return static_cast<size_t>(__cached_size_); 1082 + } 1083 + virtual char* first_demangled_name(char* buf) const 1084 + { 1085 + *buf++ = '('; 1086 + buf = __left_->get_demangled_name(buf); 1087 + *buf++ = ')'; 1088 + strncpy(buf, __name_, __size_); 1089 + return buf + __size_; 1090 + } 1091 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1092 + { 1093 + return __left_->fix_forward_references(t_begin, t_end); 1094 + } 1095 + }; 1096 + 1097 + class __operator_dereference 1098 + : public __node 1099 + { 1100 + public: 1101 + 1102 + __operator_dereference() {} 1103 + explicit __operator_dereference(__node* op) 1104 + { 1105 + __left_ = op; 1106 + } 1107 + virtual size_t first_size() const 1108 + { 1109 + if (__cached_size_ == -1) 1110 + { 1111 + if (__left_) 1112 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 1113 + else 1114 + const_cast<long&>(__cached_size_) = sizeof("operator*") - 1; 1115 + } 1116 + return static_cast<size_t>(__cached_size_); 1117 + } 1118 + virtual char* first_demangled_name(char* buf) const 1119 + { 1120 + if (__left_) 1121 + { 1122 + *buf++ = '*'; 1123 + *buf++ = '('; 1124 + buf = __left_->get_demangled_name(buf); 1125 + *buf++ = ')'; 1126 + } 1127 + else 1128 + { 1129 + strncpy(buf, "operator*", sizeof("operator*") - 1); 1130 + buf += sizeof("operator*") - 1; 1131 + } 1132 + return buf; 1133 + } 1134 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1135 + { 1136 + if (__left_) 1137 + return __left_->fix_forward_references(t_begin, t_end); 1138 + return true; 1139 + } 1140 + }; 1141 + 1142 + class __operator_divide 1143 + : public __node 1144 + { 1145 + public: 1146 + 1147 + __operator_divide() {} 1148 + __operator_divide(__node* op1, __node* op2) 1149 + { 1150 + __left_ = op1; 1151 + __right_ = op2; 1152 + } 1153 + virtual size_t first_size() const 1154 + { 1155 + if (__cached_size_ == -1) 1156 + { 1157 + if (__left_) 1158 + const_cast<long&>(__cached_size_) = static_cast<long>( 1159 + __left_->size() + 7 + 1160 + __right_->size()); 1161 + else 1162 + const_cast<long&>(__cached_size_) = sizeof("operator/") - 1; 1163 + } 1164 + return static_cast<size_t>(__cached_size_); 1165 + } 1166 + virtual char* first_demangled_name(char* buf) const 1167 + { 1168 + if (__left_) 1169 + { 1170 + *buf++ = '('; 1171 + buf = __left_->get_demangled_name(buf); 1172 + strncpy(buf, ") / (", 5); 1173 + buf += 5; 1174 + buf = __right_->get_demangled_name(buf); 1175 + *buf++ = ')'; 1176 + } 1177 + else 1178 + { 1179 + strncpy(buf, "operator/", sizeof("operator/") - 1); 1180 + buf += sizeof("operator/") - 1; 1181 + } 1182 + return buf; 1183 + } 1184 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1185 + { 1186 + bool r = true; 1187 + if (__left_) 1188 + r = r && __left_->fix_forward_references(t_begin, t_end); 1189 + if (__right_) 1190 + r = r && __right_->fix_forward_references(t_begin, t_end); 1191 + return r; 1192 + } 1193 + }; 1194 + 1195 + class __operator_divide_equal 1196 + : public __node 1197 + { 1198 + public: 1199 + 1200 + __operator_divide_equal() {} 1201 + __operator_divide_equal(__node* op1, __node* op2) 1202 + { 1203 + __left_ = op1; 1204 + __right_ = op2; 1205 + } 1206 + virtual size_t first_size() const 1207 + { 1208 + if (__cached_size_ == -1) 1209 + { 1210 + if (__left_) 1211 + const_cast<long&>(__cached_size_) = static_cast<long>( 1212 + __left_->size() + 8 + 1213 + __right_->size()); 1214 + else 1215 + const_cast<long&>(__cached_size_) = sizeof("operator/=") - 1; 1216 + } 1217 + return static_cast<size_t>(__cached_size_); 1218 + } 1219 + virtual char* first_demangled_name(char* buf) const 1220 + { 1221 + if (__left_) 1222 + { 1223 + *buf++ = '('; 1224 + buf = __left_->get_demangled_name(buf); 1225 + strncpy(buf, ") /= (", 6); 1226 + buf += 6; 1227 + buf = __right_->get_demangled_name(buf); 1228 + *buf++ = ')'; 1229 + } 1230 + else 1231 + { 1232 + strncpy(buf, "operator/=", sizeof("operator/=") - 1); 1233 + buf += sizeof("operator/=") - 1; 1234 + } 1235 + return buf; 1236 + } 1237 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1238 + { 1239 + bool r = true; 1240 + if (__left_) 1241 + r = r && __left_->fix_forward_references(t_begin, t_end); 1242 + if (__right_) 1243 + r = r && __right_->fix_forward_references(t_begin, t_end); 1244 + return r; 1245 + } 1246 + }; 1247 + 1248 + class __operator_xor 1249 + : public __node 1250 + { 1251 + public: 1252 + 1253 + __operator_xor() {} 1254 + __operator_xor(__node* op1, __node* op2) 1255 + { 1256 + __left_ = op1; 1257 + __right_ = op2; 1258 + } 1259 + virtual size_t first_size() const 1260 + { 1261 + if (__cached_size_ == -1) 1262 + { 1263 + if (__left_) 1264 + const_cast<long&>(__cached_size_) = static_cast<long>( 1265 + __left_->size() + 7 + 1266 + __right_->size()); 1267 + else 1268 + const_cast<long&>(__cached_size_) = sizeof("operator^") - 1; 1269 + } 1270 + return static_cast<size_t>(__cached_size_); 1271 + } 1272 + virtual char* first_demangled_name(char* buf) const 1273 + { 1274 + if (__left_) 1275 + { 1276 + *buf++ = '('; 1277 + buf = __left_->get_demangled_name(buf); 1278 + strncpy(buf, ") ^ (", 5); 1279 + buf += 5; 1280 + buf = __right_->get_demangled_name(buf); 1281 + *buf++ = ')'; 1282 + } 1283 + else 1284 + { 1285 + strncpy(buf, "operator^", sizeof("operator^") - 1); 1286 + buf += sizeof("operator^") - 1; 1287 + } 1288 + return buf; 1289 + } 1290 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1291 + { 1292 + bool r = true; 1293 + if (__left_) 1294 + r = r && __left_->fix_forward_references(t_begin, t_end); 1295 + if (__right_) 1296 + r = r && __right_->fix_forward_references(t_begin, t_end); 1297 + return r; 1298 + } 1299 + }; 1300 + 1301 + class __operator_xor_equal 1302 + : public __node 1303 + { 1304 + public: 1305 + 1306 + __operator_xor_equal() {} 1307 + __operator_xor_equal(__node* op1, __node* op2) 1308 + { 1309 + __left_ = op1; 1310 + __right_ = op2; 1311 + } 1312 + virtual size_t first_size() const 1313 + { 1314 + if (__cached_size_ == -1) 1315 + { 1316 + if (__left_) 1317 + const_cast<long&>(__cached_size_) = static_cast<long>( 1318 + __left_->size() + 8 + 1319 + __right_->size()); 1320 + else 1321 + const_cast<long&>(__cached_size_) = sizeof("operator^=") - 1; 1322 + } 1323 + return static_cast<size_t>(__cached_size_); 1324 + } 1325 + virtual char* first_demangled_name(char* buf) const 1326 + { 1327 + if (__left_) 1328 + { 1329 + *buf++ = '('; // strncpy(buf, "(", 1); 1330 + buf = __left_->get_demangled_name(buf); 1331 + strncpy(buf, ") ^= (", 6); 1332 + buf += 6; 1333 + buf = __right_->get_demangled_name(buf); 1334 + *buf++ = ')'; 1335 + } 1336 + else 1337 + { 1338 + strncpy(buf, "operator^=", sizeof("operator^=") - 1); 1339 + buf += sizeof("operator^=") - 1; 1340 + } 1341 + return buf; 1342 + } 1343 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1344 + { 1345 + bool r = true; 1346 + if (__left_) 1347 + r = r && __left_->fix_forward_references(t_begin, t_end); 1348 + if (__right_) 1349 + r = r && __right_->fix_forward_references(t_begin, t_end); 1350 + return r; 1351 + } 1352 + }; 1353 + 1354 + class __operator_equality 1355 + : public __node 1356 + { 1357 + public: 1358 + 1359 + __operator_equality() {} 1360 + __operator_equality(__node* op1, __node* op2) 1361 + { 1362 + __left_ = op1; 1363 + __right_ = op2; 1364 + } 1365 + virtual size_t first_size() const 1366 + { 1367 + if (__cached_size_ == -1) 1368 + { 1369 + if (__left_) 1370 + const_cast<long&>(__cached_size_) = static_cast<long>( 1371 + __left_->size() + 8 + 1372 + __right_->size()); 1373 + else 1374 + const_cast<long&>(__cached_size_) = sizeof("operator==") - 1; 1375 + } 1376 + return static_cast<size_t>(__cached_size_); 1377 + } 1378 + virtual char* first_demangled_name(char* buf) const 1379 + { 1380 + if (__left_) 1381 + { 1382 + *buf++ = '('; 1383 + buf = __left_->get_demangled_name(buf); 1384 + strncpy(buf, ") == (", 6); 1385 + buf += 6; 1386 + buf = __right_->get_demangled_name(buf); 1387 + *buf++ = ')'; 1388 + } 1389 + else 1390 + { 1391 + strncpy(buf, "operator==", sizeof("operator==") - 1); 1392 + buf += sizeof("operator==") - 1; 1393 + } 1394 + return buf; 1395 + } 1396 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1397 + { 1398 + bool r = true; 1399 + if (__left_) 1400 + r = r && __left_->fix_forward_references(t_begin, t_end); 1401 + if (__right_) 1402 + r = r && __right_->fix_forward_references(t_begin, t_end); 1403 + return r; 1404 + } 1405 + }; 1406 + 1407 + class __operator_greater_equal 1408 + : public __node 1409 + { 1410 + public: 1411 + 1412 + __operator_greater_equal() {} 1413 + __operator_greater_equal(__node* op1, __node* op2) 1414 + { 1415 + __left_ = op1; 1416 + __right_ = op2; 1417 + } 1418 + virtual size_t first_size() const 1419 + { 1420 + if (__cached_size_ == -1) 1421 + { 1422 + if (__left_) 1423 + const_cast<long&>(__cached_size_) = static_cast<long>( 1424 + __left_->size() + 8 + 1425 + __right_->size()); 1426 + else 1427 + const_cast<long&>(__cached_size_) = sizeof("operator>=") - 1; 1428 + } 1429 + return static_cast<size_t>(__cached_size_); 1430 + } 1431 + virtual char* first_demangled_name(char* buf) const 1432 + { 1433 + if (__left_) 1434 + { 1435 + *buf++ = '('; 1436 + buf = __left_->get_demangled_name(buf); 1437 + strncpy(buf, ") >= (", 6); 1438 + buf += 6; 1439 + buf = __right_->get_demangled_name(buf); 1440 + *buf++ = ')'; 1441 + } 1442 + else 1443 + { 1444 + strncpy(buf, "operator>=", sizeof("operator>=") - 1); 1445 + buf += sizeof("operator>=") - 1; 1446 + } 1447 + return buf; 1448 + } 1449 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1450 + { 1451 + bool r = true; 1452 + if (__left_) 1453 + r = r && __left_->fix_forward_references(t_begin, t_end); 1454 + if (__right_) 1455 + r = r && __right_->fix_forward_references(t_begin, t_end); 1456 + return r; 1457 + } 1458 + }; 1459 + 1460 + class __operator_greater 1461 + : public __node 1462 + { 1463 + public: 1464 + 1465 + __operator_greater() {} 1466 + __operator_greater(__node* op1, __node* op2) 1467 + { 1468 + __left_ = op1; 1469 + __right_ = op2; 1470 + } 1471 + virtual size_t first_size() const 1472 + { 1473 + if (__cached_size_ == -1) 1474 + { 1475 + if (__left_) 1476 + const_cast<long&>(__cached_size_) = static_cast<long>( 1477 + __left_->size() + 9 + 1478 + __right_->size()); 1479 + else 1480 + const_cast<long&>(__cached_size_) = sizeof("operator>") - 1; 1481 + } 1482 + return static_cast<size_t>(__cached_size_); 1483 + } 1484 + virtual char* first_demangled_name(char* buf) const 1485 + { 1486 + if (__left_) 1487 + { 1488 + *buf++ = '('; 1489 + *buf++ = '('; 1490 + buf = __left_->get_demangled_name(buf); 1491 + strncpy(buf, ") > (", 5); 1492 + buf += 5; 1493 + buf = __right_->get_demangled_name(buf); 1494 + *buf++ = ')'; 1495 + *buf++ = ')'; 1496 + } 1497 + else 1498 + { 1499 + strncpy(buf, "operator>", sizeof("operator>") - 1); 1500 + buf += sizeof("operator>") - 1; 1501 + } 1502 + return buf; 1503 + } 1504 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1505 + { 1506 + bool r = true; 1507 + if (__left_) 1508 + r = r && __left_->fix_forward_references(t_begin, t_end); 1509 + if (__right_) 1510 + r = r && __right_->fix_forward_references(t_begin, t_end); 1511 + return r; 1512 + } 1513 + }; 1514 + 1515 + class __operator_brackets 1516 + : public __node 1517 + { 1518 + public: 1519 + 1520 + virtual size_t first_size() const {return sizeof("operator[]") - 1;} 1521 + virtual char* first_demangled_name(char* buf) const 1522 + { 1523 + strncpy(buf, "operator[]", sizeof("operator[]") - 1); 1524 + return buf + sizeof("operator[]") - 1; 1525 + } 1526 + }; 1527 + 1528 + class __operator_less_equal 1529 + : public __node 1530 + { 1531 + public: 1532 + 1533 + __operator_less_equal() {} 1534 + __operator_less_equal(__node* op1, __node* op2) 1535 + { 1536 + __left_ = op1; 1537 + __right_ = op2; 1538 + } 1539 + virtual size_t first_size() const 1540 + { 1541 + if (__cached_size_ == -1) 1542 + { 1543 + if (__left_) 1544 + const_cast<long&>(__cached_size_) = static_cast<long>( 1545 + __left_->size() + 8 + 1546 + __right_->size()); 1547 + else 1548 + const_cast<long&>(__cached_size_) = sizeof("operator<=") - 1; 1549 + } 1550 + return static_cast<size_t>(__cached_size_); 1551 + } 1552 + virtual char* first_demangled_name(char* buf) const 1553 + { 1554 + if (__left_) 1555 + { 1556 + *buf++ = '('; 1557 + buf = __left_->get_demangled_name(buf); 1558 + strncpy(buf, ") <= (", 6); 1559 + buf += 6; 1560 + buf = __right_->get_demangled_name(buf); 1561 + *buf++ = ')'; 1562 + } 1563 + else 1564 + { 1565 + strncpy(buf, "operator<=", sizeof("operator<=") - 1); 1566 + buf += sizeof("operator<=") - 1; 1567 + } 1568 + return buf; 1569 + } 1570 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1571 + { 1572 + bool r = true; 1573 + if (__left_) 1574 + r = r && __left_->fix_forward_references(t_begin, t_end); 1575 + if (__right_) 1576 + r = r && __right_->fix_forward_references(t_begin, t_end); 1577 + return r; 1578 + } 1579 + }; 1580 + 1581 + class __operator_less 1582 + : public __node 1583 + { 1584 + public: 1585 + 1586 + __operator_less() {} 1587 + __operator_less(__node* op1, __node* op2) 1588 + { 1589 + __left_ = op1; 1590 + __right_ = op2; 1591 + } 1592 + virtual size_t first_size() const 1593 + { 1594 + if (__cached_size_ == -1) 1595 + { 1596 + if (__left_) 1597 + const_cast<long&>(__cached_size_) = static_cast<long>( 1598 + __left_->size() + 7 + 1599 + __right_->size()); 1600 + else 1601 + const_cast<long&>(__cached_size_) = sizeof("operator<") - 1; 1602 + } 1603 + return static_cast<size_t>(__cached_size_); 1604 + } 1605 + virtual char* first_demangled_name(char* buf) const 1606 + { 1607 + if (__left_) 1608 + { 1609 + *buf++ = '('; 1610 + buf = __left_->get_demangled_name(buf); 1611 + strncpy(buf, ") < (", 5); 1612 + buf += 5; 1613 + buf = __right_->get_demangled_name(buf); 1614 + *buf++ = ')'; 1615 + } 1616 + else 1617 + { 1618 + strncpy(buf, "operator<", sizeof("operator<") - 1); 1619 + buf += sizeof("operator<") - 1; 1620 + } 1621 + return buf; 1622 + } 1623 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1624 + { 1625 + bool r = true; 1626 + if (__left_) 1627 + r = r && __left_->fix_forward_references(t_begin, t_end); 1628 + if (__right_) 1629 + r = r && __right_->fix_forward_references(t_begin, t_end); 1630 + return r; 1631 + } 1632 + }; 1633 + 1634 + class __operator_left_shift 1635 + : public __node 1636 + { 1637 + public: 1638 + 1639 + __operator_left_shift() {} 1640 + __operator_left_shift(__node* op1, __node* op2) 1641 + { 1642 + __left_ = op1; 1643 + __right_ = op2; 1644 + } 1645 + virtual size_t first_size() const 1646 + { 1647 + if (__cached_size_ == -1) 1648 + { 1649 + if (__left_) 1650 + const_cast<long&>(__cached_size_) = static_cast<long>( 1651 + __left_->size() + 8 + 1652 + __right_->size()); 1653 + else 1654 + const_cast<long&>(__cached_size_) = sizeof("operator<<") - 1; 1655 + } 1656 + return static_cast<size_t>(__cached_size_); 1657 + } 1658 + virtual char* first_demangled_name(char* buf) const 1659 + { 1660 + if (__left_) 1661 + { 1662 + *buf++ = '('; 1663 + buf = __left_->get_demangled_name(buf); 1664 + strncpy(buf, ") << (", 6); 1665 + buf += 6; 1666 + buf = __right_->get_demangled_name(buf); 1667 + *buf++ = ')'; 1668 + } 1669 + else 1670 + { 1671 + strncpy(buf, "operator<<", sizeof("operator<<") - 1); 1672 + buf += sizeof("operator<<") - 1; 1673 + } 1674 + return buf; 1675 + } 1676 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1677 + { 1678 + bool r = true; 1679 + if (__left_) 1680 + r = r && __left_->fix_forward_references(t_begin, t_end); 1681 + if (__right_) 1682 + r = r && __right_->fix_forward_references(t_begin, t_end); 1683 + return r; 1684 + } 1685 + }; 1686 + 1687 + class __operator_left_shift_equal 1688 + : public __node 1689 + { 1690 + public: 1691 + 1692 + __operator_left_shift_equal() {} 1693 + __operator_left_shift_equal(__node* op1, __node* op2) 1694 + { 1695 + __left_ = op1; 1696 + __right_ = op2; 1697 + } 1698 + virtual size_t first_size() const 1699 + { 1700 + if (__cached_size_ == -1) 1701 + { 1702 + if (__left_) 1703 + const_cast<long&>(__cached_size_) = static_cast<long>( 1704 + __left_->size() + 9 + 1705 + __right_->size()); 1706 + else 1707 + const_cast<long&>(__cached_size_) = sizeof("operator<<=") - 1; 1708 + } 1709 + return static_cast<size_t>(__cached_size_); 1710 + } 1711 + virtual char* first_demangled_name(char* buf) const 1712 + { 1713 + if (__left_) 1714 + { 1715 + *buf++ = '('; 1716 + buf = __left_->get_demangled_name(buf); 1717 + strncpy(buf, ") <<= (", 7); 1718 + buf += 7; 1719 + buf = __right_->get_demangled_name(buf); 1720 + *buf++ = ')'; 1721 + } 1722 + else 1723 + { 1724 + strncpy(buf, "operator<<=", sizeof("operator<<=") - 1); 1725 + buf += sizeof("operator<<=") - 1; 1726 + } 1727 + return buf; 1728 + } 1729 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1730 + { 1731 + bool r = true; 1732 + if (__left_) 1733 + r = r && __left_->fix_forward_references(t_begin, t_end); 1734 + if (__right_) 1735 + r = r && __right_->fix_forward_references(t_begin, t_end); 1736 + return r; 1737 + } 1738 + }; 1739 + 1740 + class __operator_minus 1741 + : public __node 1742 + { 1743 + public: 1744 + 1745 + __operator_minus() {} 1746 + __operator_minus(__node* op1, __node* op2) 1747 + { 1748 + __left_ = op1; 1749 + __right_ = op2; 1750 + } 1751 + virtual size_t first_size() const 1752 + { 1753 + if (__cached_size_ == -1) 1754 + { 1755 + if (__left_) 1756 + const_cast<long&>(__cached_size_) = static_cast<long>( 1757 + __left_->size() + 7 + 1758 + __right_->size()); 1759 + else 1760 + const_cast<long&>(__cached_size_) = sizeof("operator-") - 1; 1761 + } 1762 + return static_cast<size_t>(__cached_size_); 1763 + } 1764 + virtual char* first_demangled_name(char* buf) const 1765 + { 1766 + if (__left_) 1767 + { 1768 + *buf++ = '('; 1769 + buf = __left_->get_demangled_name(buf); 1770 + strncpy(buf, ") - (", 5); 1771 + buf += 5; 1772 + buf = __right_->get_demangled_name(buf); 1773 + *buf++ = ')'; 1774 + } 1775 + else 1776 + { 1777 + strncpy(buf, "operator-", sizeof("operator-") - 1); 1778 + buf += sizeof("operator-") - 1; 1779 + } 1780 + return buf; 1781 + } 1782 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1783 + { 1784 + bool r = true; 1785 + if (__left_) 1786 + r = r && __left_->fix_forward_references(t_begin, t_end); 1787 + if (__right_) 1788 + r = r && __right_->fix_forward_references(t_begin, t_end); 1789 + return r; 1790 + } 1791 + }; 1792 + 1793 + class __operator_minus_equal 1794 + : public __node 1795 + { 1796 + public: 1797 + 1798 + __operator_minus_equal() {} 1799 + __operator_minus_equal(__node* op1, __node* op2) 1800 + { 1801 + __left_ = op1; 1802 + __right_ = op2; 1803 + } 1804 + virtual size_t first_size() const 1805 + { 1806 + if (__cached_size_ == -1) 1807 + { 1808 + if (__left_) 1809 + const_cast<long&>(__cached_size_) = static_cast<long>( 1810 + __left_->size() + 8 + 1811 + __right_->size()); 1812 + else 1813 + const_cast<long&>(__cached_size_) = sizeof("operator-=") - 1; 1814 + } 1815 + return static_cast<size_t>(__cached_size_); 1816 + } 1817 + virtual char* first_demangled_name(char* buf) const 1818 + { 1819 + if (__left_) 1820 + { 1821 + *buf++ = '('; 1822 + buf = __left_->get_demangled_name(buf); 1823 + strncpy(buf, ") -= (", 6); 1824 + buf += 6; 1825 + buf = __right_->get_demangled_name(buf); 1826 + *buf++ = ')'; 1827 + } 1828 + else 1829 + { 1830 + strncpy(buf, "operator-=", sizeof("operator-=") - 1); 1831 + buf += sizeof("operator-=") - 1; 1832 + } 1833 + return buf; 1834 + } 1835 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1836 + { 1837 + bool r = true; 1838 + if (__left_) 1839 + r = r && __left_->fix_forward_references(t_begin, t_end); 1840 + if (__right_) 1841 + r = r && __right_->fix_forward_references(t_begin, t_end); 1842 + return r; 1843 + } 1844 + }; 1845 + 1846 + class __operator_times 1847 + : public __node 1848 + { 1849 + public: 1850 + 1851 + __operator_times() {} 1852 + __operator_times(__node* op1, __node* op2) 1853 + { 1854 + __left_ = op1; 1855 + __right_ = op2; 1856 + } 1857 + virtual size_t first_size() const 1858 + { 1859 + if (__cached_size_ == -1) 1860 + { 1861 + if (__left_) 1862 + const_cast<long&>(__cached_size_) = static_cast<long>( 1863 + __left_->size() + 7 + 1864 + __right_->size()); 1865 + else 1866 + const_cast<long&>(__cached_size_) = sizeof("operator*") - 1; 1867 + } 1868 + return static_cast<size_t>(__cached_size_); 1869 + } 1870 + virtual char* first_demangled_name(char* buf) const 1871 + { 1872 + if (__left_) 1873 + { 1874 + *buf++ = '('; 1875 + buf = __left_->get_demangled_name(buf); 1876 + strncpy(buf, ") * (", 5); 1877 + buf += 5; 1878 + buf = __right_->get_demangled_name(buf); 1879 + *buf++ = ')'; 1880 + } 1881 + else 1882 + { 1883 + strncpy(buf, "operator*", sizeof("operator*") - 1); 1884 + buf += sizeof("operator*") - 1; 1885 + } 1886 + return buf; 1887 + } 1888 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1889 + { 1890 + bool r = true; 1891 + if (__left_) 1892 + r = r && __left_->fix_forward_references(t_begin, t_end); 1893 + if (__right_) 1894 + r = r && __right_->fix_forward_references(t_begin, t_end); 1895 + return r; 1896 + } 1897 + }; 1898 + 1899 + class __operator_times_equal 1900 + : public __node 1901 + { 1902 + public: 1903 + 1904 + __operator_times_equal() {} 1905 + __operator_times_equal(__node* op1, __node* op2) 1906 + { 1907 + __left_ = op1; 1908 + __right_ = op2; 1909 + } 1910 + virtual size_t first_size() const 1911 + { 1912 + if (__cached_size_ == -1) 1913 + { 1914 + if (__left_) 1915 + const_cast<long&>(__cached_size_) = static_cast<long>( 1916 + __left_->size() + 8 + 1917 + __right_->size()); 1918 + else 1919 + const_cast<long&>(__cached_size_) = sizeof("operator*=") - 1; 1920 + } 1921 + return static_cast<size_t>(__cached_size_); 1922 + } 1923 + virtual char* first_demangled_name(char* buf) const 1924 + { 1925 + if (__left_) 1926 + { 1927 + *buf++ = '('; 1928 + buf = __left_->get_demangled_name(buf); 1929 + strncpy(buf, ") *= (", 6); 1930 + buf += 6; 1931 + buf = __right_->get_demangled_name(buf); 1932 + *buf++ = ')'; 1933 + } 1934 + else 1935 + { 1936 + strncpy(buf, "operator*=", sizeof("operator*=") - 1); 1937 + buf += sizeof("operator*=") - 1; 1938 + } 1939 + return buf; 1940 + } 1941 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 1942 + { 1943 + bool r = true; 1944 + if (__left_) 1945 + r = r && __left_->fix_forward_references(t_begin, t_end); 1946 + if (__right_) 1947 + r = r && __right_->fix_forward_references(t_begin, t_end); 1948 + return r; 1949 + } 1950 + }; 1951 + 1952 + class __operator_decrement 1953 + : public __node 1954 + { 1955 + public: 1956 + 1957 + __operator_decrement() {} 1958 + explicit __operator_decrement(bool prefix, __node* op) 1959 + { 1960 + __size_ = prefix; 1961 + __left_ = op; 1962 + } 1963 + virtual size_t first_size() const 1964 + { 1965 + if (__cached_size_ == -1) 1966 + { 1967 + if (__left_) 1968 + const_cast<long&>(__cached_size_) = static_cast<long>(4 + __left_->size()); 1969 + else 1970 + const_cast<long&>(__cached_size_) = sizeof("operator--") - 1; 1971 + } 1972 + return static_cast<size_t>(__cached_size_); 1973 + } 1974 + virtual char* first_demangled_name(char* buf) const 1975 + { 1976 + if (__left_) 1977 + { 1978 + if (__size_) 1979 + { 1980 + *buf++ = '-'; 1981 + *buf++ = '-'; 1982 + *buf++ = '('; 1983 + } 1984 + else 1985 + *buf++ = '('; 1986 + buf = __left_->get_demangled_name(buf); 1987 + if (__size_) 1988 + *buf++ = ')'; 1989 + else 1990 + { 1991 + *buf++ = ')'; 1992 + *buf++ = '-'; 1993 + *buf++ = '-'; 1994 + } 1995 + } 1996 + else 1997 + { 1998 + strncpy(buf, "operator--", sizeof("operator--") - 1); 1999 + buf += sizeof("operator--") - 1; 2000 + } 2001 + return buf; 2002 + } 2003 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2004 + { 2005 + if (__left_) 2006 + return __left_->fix_forward_references(t_begin, t_end); 2007 + return true; 2008 + } 2009 + }; 2010 + 2011 + class __operator_not_equal 2012 + : public __node 2013 + { 2014 + public: 2015 + 2016 + __operator_not_equal() {} 2017 + __operator_not_equal(__node* op1, __node* op2) 2018 + { 2019 + __left_ = op1; 2020 + __right_ = op2; 2021 + } 2022 + virtual size_t first_size() const 2023 + { 2024 + if (__cached_size_ == -1) 2025 + { 2026 + if (__left_) 2027 + const_cast<long&>(__cached_size_) = static_cast<long>( 2028 + __left_->size() + 8 + 2029 + __right_->size()); 2030 + else 2031 + const_cast<long&>(__cached_size_) = sizeof("operator!=") - 1; 2032 + } 2033 + return static_cast<size_t>(__cached_size_); 2034 + } 2035 + virtual char* first_demangled_name(char* buf) const 2036 + { 2037 + if (__left_) 2038 + { 2039 + *buf++ = '('; 2040 + buf = __left_->get_demangled_name(buf); 2041 + strncpy(buf, ") != (", 6); 2042 + buf += 6; 2043 + buf = __right_->get_demangled_name(buf); 2044 + *buf++ = ')'; 2045 + } 2046 + else 2047 + { 2048 + strncpy(buf, "operator!=", sizeof("operator!=") - 1); 2049 + buf += sizeof("operator!=") - 1; 2050 + } 2051 + return buf; 2052 + } 2053 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2054 + { 2055 + bool r = true; 2056 + if (__left_) 2057 + r = r && __left_->fix_forward_references(t_begin, t_end); 2058 + if (__right_) 2059 + r = r && __right_->fix_forward_references(t_begin, t_end); 2060 + return r; 2061 + } 2062 + }; 2063 + 2064 + class __operator_negate 2065 + : public __node 2066 + { 2067 + public: 2068 + 2069 + __operator_negate() {} 2070 + explicit __operator_negate(__node* op) 2071 + { 2072 + __left_ = op; 2073 + } 2074 + virtual size_t first_size() const 2075 + { 2076 + if (__cached_size_ == -1) 2077 + { 2078 + if (__left_) 2079 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 2080 + else 2081 + const_cast<long&>(__cached_size_) = sizeof("operator-") - 1; 2082 + } 2083 + return static_cast<size_t>(__cached_size_); 2084 + } 2085 + virtual char* first_demangled_name(char* buf) const 2086 + { 2087 + if (__left_) 2088 + { 2089 + *buf++ = '-'; 2090 + *buf++ = '('; 2091 + buf = __left_->get_demangled_name(buf); 2092 + *buf++ = ')'; 2093 + } 2094 + else 2095 + { 2096 + strncpy(buf, "operator-", sizeof("operator-") - 1); 2097 + buf += sizeof("operator-") - 1; 2098 + } 2099 + return buf; 2100 + } 2101 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2102 + { 2103 + if (__left_) 2104 + return __left_->fix_forward_references(t_begin, t_end); 2105 + return true; 2106 + } 2107 + }; 2108 + 2109 + class __operator_logical_not 2110 + : public __node 2111 + { 2112 + public: 2113 + 2114 + __operator_logical_not() {} 2115 + explicit __operator_logical_not(__node* op) 2116 + { 2117 + __left_ = op; 2118 + } 2119 + virtual size_t first_size() const 2120 + { 2121 + if (__cached_size_ == -1) 2122 + { 2123 + if (__left_) 2124 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 2125 + else 2126 + const_cast<long&>(__cached_size_) = sizeof("operator!") - 1; 2127 + } 2128 + return static_cast<size_t>(__cached_size_); 2129 + } 2130 + virtual char* first_demangled_name(char* buf) const 2131 + { 2132 + if (__left_) 2133 + { 2134 + *buf++ = '!'; 2135 + *buf++ = '('; 2136 + buf = __left_->get_demangled_name(buf); 2137 + *buf++ = ')'; 2138 + } 2139 + else 2140 + { 2141 + strncpy(buf, "operator!", sizeof("operator!") - 1); 2142 + buf += sizeof("operator!") - 1; 2143 + } 2144 + return buf; 2145 + } 2146 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2147 + { 2148 + if (__left_) 2149 + return __left_->fix_forward_references(t_begin, t_end); 2150 + return true; 2151 + } 2152 + }; 2153 + 2154 + class __operator_logical_or 2155 + : public __node 2156 + { 2157 + public: 2158 + 2159 + __operator_logical_or() {} 2160 + __operator_logical_or(__node* op1, __node* op2) 2161 + { 2162 + __left_ = op1; 2163 + __right_ = op2; 2164 + } 2165 + virtual size_t first_size() const 2166 + { 2167 + if (__cached_size_ == -1) 2168 + { 2169 + if (__left_) 2170 + const_cast<long&>(__cached_size_) = static_cast<long>( 2171 + __left_->size() + 8 + 2172 + __right_->size()); 2173 + else 2174 + const_cast<long&>(__cached_size_) = sizeof("operator||") - 1; 2175 + } 2176 + return static_cast<size_t>(__cached_size_); 2177 + } 2178 + virtual char* first_demangled_name(char* buf) const 2179 + { 2180 + if (__left_) 2181 + { 2182 + *buf++ = '('; 2183 + buf = __left_->get_demangled_name(buf); 2184 + strncpy(buf, ") || (", 6); 2185 + buf += 6; 2186 + buf = __right_->get_demangled_name(buf); 2187 + *buf++ = ')'; 2188 + } 2189 + else 2190 + { 2191 + strncpy(buf, "operator||", sizeof("operator||") - 1); 2192 + buf += sizeof("operator||") - 1; 2193 + } 2194 + return buf; 2195 + } 2196 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2197 + { 2198 + bool r = true; 2199 + if (__left_) 2200 + r = r && __left_->fix_forward_references(t_begin, t_end); 2201 + if (__right_) 2202 + r = r && __right_->fix_forward_references(t_begin, t_end); 2203 + return r; 2204 + } 2205 + }; 2206 + 2207 + class __operator_bit_or 2208 + : public __node 2209 + { 2210 + public: 2211 + 2212 + __operator_bit_or() {} 2213 + __operator_bit_or(__node* op1, __node* op2) 2214 + { 2215 + __left_ = op1; 2216 + __right_ = op2; 2217 + } 2218 + virtual size_t first_size() const 2219 + { 2220 + if (__cached_size_ == -1) 2221 + { 2222 + if (__left_) 2223 + const_cast<long&>(__cached_size_) = static_cast<long>( 2224 + __left_->size() + 7 + 2225 + __right_->size()); 2226 + else 2227 + const_cast<long&>(__cached_size_) = sizeof("operator|") - 1; 2228 + } 2229 + return static_cast<size_t>(__cached_size_); 2230 + } 2231 + virtual char* first_demangled_name(char* buf) const 2232 + { 2233 + if (__left_) 2234 + { 2235 + *buf++ = '('; 2236 + buf = __left_->get_demangled_name(buf); 2237 + strncpy(buf, ") | (", 5); 2238 + buf += 5; 2239 + buf = __right_->get_demangled_name(buf); 2240 + *buf++ = ')'; 2241 + } 2242 + else 2243 + { 2244 + strncpy(buf, "operator|", sizeof("operator|") - 1); 2245 + buf += sizeof("operator|") - 1; 2246 + } 2247 + return buf; 2248 + } 2249 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2250 + { 2251 + bool r = true; 2252 + if (__left_) 2253 + r = r && __left_->fix_forward_references(t_begin, t_end); 2254 + if (__right_) 2255 + r = r && __right_->fix_forward_references(t_begin, t_end); 2256 + return r; 2257 + } 2258 + }; 2259 + 2260 + class __operator_or_equal 2261 + : public __node 2262 + { 2263 + public: 2264 + 2265 + __operator_or_equal() {} 2266 + __operator_or_equal(__node* op1, __node* op2) 2267 + { 2268 + __left_ = op1; 2269 + __right_ = op2; 2270 + } 2271 + virtual size_t first_size() const 2272 + { 2273 + if (__cached_size_ == -1) 2274 + { 2275 + if (__left_) 2276 + const_cast<long&>(__cached_size_) = static_cast<long>( 2277 + __left_->size() + 8 + 2278 + __right_->size()); 2279 + else 2280 + const_cast<long&>(__cached_size_) = sizeof("operator|=") - 1; 2281 + } 2282 + return static_cast<size_t>(__cached_size_); 2283 + } 2284 + virtual char* first_demangled_name(char* buf) const 2285 + { 2286 + if (__left_) 2287 + { 2288 + *buf++ = '('; 2289 + buf = __left_->get_demangled_name(buf); 2290 + strncpy(buf, ") |= (", 6); 2291 + buf += 6; 2292 + buf = __right_->get_demangled_name(buf); 2293 + *buf++ = ')'; 2294 + } 2295 + else 2296 + { 2297 + strncpy(buf, "operator|=", sizeof("operator|=") - 1); 2298 + buf += sizeof("operator|=") - 1; 2299 + } 2300 + return buf; 2301 + } 2302 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2303 + { 2304 + bool r = true; 2305 + if (__left_) 2306 + r = r && __left_->fix_forward_references(t_begin, t_end); 2307 + if (__right_) 2308 + r = r && __right_->fix_forward_references(t_begin, t_end); 2309 + return r; 2310 + } 2311 + }; 2312 + 2313 + class __operator_pointer_to_member 2314 + : public __node 2315 + { 2316 + public: 2317 + 2318 + __operator_pointer_to_member() {} 2319 + __operator_pointer_to_member(__node* op1, __node* op2) 2320 + { 2321 + __left_ = op1; 2322 + __right_ = op2; 2323 + } 2324 + virtual size_t first_size() const 2325 + { 2326 + if (__cached_size_ == -1) 2327 + { 2328 + if (__left_) 2329 + const_cast<long&>(__cached_size_) = static_cast<long>( 2330 + __left_->size() + 9 + 2331 + __right_->size()); 2332 + else 2333 + const_cast<long&>(__cached_size_) = sizeof("operator->*") - 1; 2334 + } 2335 + return static_cast<size_t>(__cached_size_); 2336 + } 2337 + virtual char* first_demangled_name(char* buf) const 2338 + { 2339 + if (__left_) 2340 + { 2341 + *buf++ = '('; 2342 + buf = __left_->get_demangled_name(buf); 2343 + strncpy(buf, ") ->* (", 7); 2344 + buf += 7; 2345 + buf = __right_->get_demangled_name(buf); 2346 + *buf++ = ')'; 2347 + } 2348 + else 2349 + { 2350 + strncpy(buf, "operator->*", sizeof("operator->*") - 1); 2351 + buf += sizeof("operator->*") - 1; 2352 + } 2353 + return buf; 2354 + } 2355 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2356 + { 2357 + bool r = true; 2358 + if (__left_) 2359 + r = r && __left_->fix_forward_references(t_begin, t_end); 2360 + if (__right_) 2361 + r = r && __right_->fix_forward_references(t_begin, t_end); 2362 + return r; 2363 + } 2364 + }; 2365 + 2366 + class __operator_plus 2367 + : public __node 2368 + { 2369 + public: 2370 + 2371 + __operator_plus() {} 2372 + __operator_plus(__node* op1, __node* op2) 2373 + { 2374 + __left_ = op1; 2375 + __right_ = op2; 2376 + } 2377 + virtual size_t first_size() const 2378 + { 2379 + if (__cached_size_ == -1) 2380 + { 2381 + if (__left_) 2382 + const_cast<long&>(__cached_size_) = static_cast<long>( 2383 + __left_->size() + 7 + 2384 + __right_->size()); 2385 + else 2386 + const_cast<long&>(__cached_size_) = sizeof("operator+") - 1; 2387 + } 2388 + return static_cast<size_t>(__cached_size_); 2389 + } 2390 + virtual char* first_demangled_name(char* buf) const 2391 + { 2392 + if (__left_) 2393 + { 2394 + *buf++ = '('; 2395 + buf = __left_->get_demangled_name(buf); 2396 + strncpy(buf, ") + (", 5); 2397 + buf += 5; 2398 + buf = __right_->get_demangled_name(buf); 2399 + *buf++ = ')'; 2400 + } 2401 + else 2402 + { 2403 + strncpy(buf, "operator+", sizeof("operator+") - 1); 2404 + buf += sizeof("operator+") - 1; 2405 + } 2406 + return buf; 2407 + } 2408 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2409 + { 2410 + bool r = true; 2411 + if (__left_) 2412 + r = r && __left_->fix_forward_references(t_begin, t_end); 2413 + if (__right_) 2414 + r = r && __right_->fix_forward_references(t_begin, t_end); 2415 + return r; 2416 + } 2417 + }; 2418 + 2419 + class __operator_plus_equal 2420 + : public __node 2421 + { 2422 + public: 2423 + 2424 + __operator_plus_equal() {} 2425 + __operator_plus_equal(__node* op1, __node* op2) 2426 + { 2427 + __left_ = op1; 2428 + __right_ = op2; 2429 + } 2430 + virtual size_t first_size() const 2431 + { 2432 + if (__cached_size_ == -1) 2433 + { 2434 + if (__left_) 2435 + const_cast<long&>(__cached_size_) = static_cast<long>( 2436 + __left_->size() + 8 + 2437 + __right_->size()); 2438 + else 2439 + const_cast<long&>(__cached_size_) = sizeof("operator+=") - 1; 2440 + } 2441 + return static_cast<size_t>(__cached_size_); 2442 + } 2443 + virtual char* first_demangled_name(char* buf) const 2444 + { 2445 + if (__left_) 2446 + { 2447 + *buf++ = '('; 2448 + buf = __left_->get_demangled_name(buf); 2449 + strncpy(buf, ") += (", 6); 2450 + buf += 6; 2451 + buf = __right_->get_demangled_name(buf); 2452 + *buf++ = ')'; 2453 + } 2454 + else 2455 + { 2456 + strncpy(buf, "operator+=", sizeof("operator+=") - 1); 2457 + buf += sizeof("operator+=") - 1; 2458 + } 2459 + return buf; 2460 + } 2461 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2462 + { 2463 + bool r = true; 2464 + if (__left_) 2465 + r = r && __left_->fix_forward_references(t_begin, t_end); 2466 + if (__right_) 2467 + r = r && __right_->fix_forward_references(t_begin, t_end); 2468 + return r; 2469 + } 2470 + }; 2471 + 2472 + class __operator_increment 2473 + : public __node 2474 + { 2475 + public: 2476 + 2477 + __operator_increment() {} 2478 + explicit __operator_increment(bool prefix, __node* op) 2479 + { 2480 + __size_ = prefix; 2481 + __left_ = op; 2482 + } 2483 + virtual size_t first_size() const 2484 + { 2485 + if (__cached_size_ == -1) 2486 + { 2487 + if (__left_) 2488 + const_cast<long&>(__cached_size_) = static_cast<long>(4 + __left_->size()); 2489 + else 2490 + const_cast<long&>(__cached_size_) = sizeof("operator++") - 1; 2491 + } 2492 + return static_cast<size_t>(__cached_size_); 2493 + } 2494 + virtual char* first_demangled_name(char* buf) const 2495 + { 2496 + if (__left_) 2497 + { 2498 + if (__size_) 2499 + { 2500 + *buf++ = '+'; 2501 + *buf++ = '+'; 2502 + *buf++ = '('; 2503 + } 2504 + else 2505 + *buf++ = '('; 2506 + buf = __left_->get_demangled_name(buf); 2507 + if (__size_) 2508 + *buf++ = ')'; 2509 + else 2510 + { 2511 + *buf++ = ')'; 2512 + *buf++ = '+'; 2513 + *buf++ = '+'; 2514 + } 2515 + } 2516 + else 2517 + { 2518 + strncpy(buf, "operator++", sizeof("operator++") - 1); 2519 + buf += sizeof("operator++") - 1; 2520 + } 2521 + return buf; 2522 + } 2523 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2524 + { 2525 + if (__left_) 2526 + return __left_->fix_forward_references(t_begin, t_end); 2527 + return true; 2528 + } 2529 + }; 2530 + 2531 + class __operator_unary_plus 2532 + : public __node 2533 + { 2534 + public: 2535 + 2536 + __operator_unary_plus() {} 2537 + explicit __operator_unary_plus(__node* op) 2538 + { 2539 + __left_ = op; 2540 + } 2541 + virtual size_t first_size() const 2542 + { 2543 + if (__cached_size_ == -1) 2544 + { 2545 + if (__left_) 2546 + const_cast<long&>(__cached_size_) = static_cast<long>(3 + __left_->size()); 2547 + else 2548 + const_cast<long&>(__cached_size_) = sizeof("operator+") - 1; 2549 + } 2550 + return static_cast<size_t>(__cached_size_); 2551 + } 2552 + virtual char* first_demangled_name(char* buf) const 2553 + { 2554 + if (__left_) 2555 + { 2556 + *buf++ = '+'; 2557 + *buf++ = '('; 2558 + buf = __left_->get_demangled_name(buf); 2559 + *buf++ = ')'; 2560 + } 2561 + else 2562 + { 2563 + strncpy(buf, "operator+", sizeof("operator+") - 1); 2564 + buf += sizeof("operator+") - 1; 2565 + } 2566 + return buf; 2567 + } 2568 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2569 + { 2570 + if (__left_) 2571 + return __left_->fix_forward_references(t_begin, t_end); 2572 + return true; 2573 + } 2574 + }; 2575 + 2576 + class __operator_arrow 2577 + : public __node 2578 + { 2579 + public: 2580 + 2581 + __operator_arrow() {} 2582 + __operator_arrow(__node* op1, __node* op2) 2583 + { 2584 + __left_ = op1; 2585 + __right_ = op2; 2586 + } 2587 + virtual size_t first_size() const 2588 + { 2589 + if (__cached_size_ == -1) 2590 + { 2591 + if (__left_) 2592 + const_cast<long&>(__cached_size_) = static_cast<long>( 2593 + __left_->size() + 8 + 2594 + __right_->size()); 2595 + else 2596 + const_cast<long&>(__cached_size_) = sizeof("operator->") - 1; 2597 + } 2598 + return static_cast<size_t>(__cached_size_); 2599 + } 2600 + virtual char* first_demangled_name(char* buf) const 2601 + { 2602 + if (__left_) 2603 + { 2604 + *buf++ = '('; 2605 + buf = __left_->get_demangled_name(buf); 2606 + strncpy(buf, ") -> (", 6); 2607 + buf += 6; 2608 + buf = __right_->get_demangled_name(buf); 2609 + *buf++ = ')'; 2610 + } 2611 + else 2612 + { 2613 + strncpy(buf, "operator->", sizeof("operator->") - 1); 2614 + buf += sizeof("operator->") - 1; 2615 + } 2616 + return buf; 2617 + } 2618 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2619 + { 2620 + bool r = true; 2621 + if (__left_) 2622 + r = r && __left_->fix_forward_references(t_begin, t_end); 2623 + if (__right_) 2624 + r = r && __right_->fix_forward_references(t_begin, t_end); 2625 + return r; 2626 + } 2627 + }; 2628 + 2629 + class __operator_conditional 2630 + : public __node 2631 + { 2632 + public: 2633 + 2634 + __operator_conditional() {} 2635 + __operator_conditional(__node* op1, __node* op2, __node* op3) 2636 + { 2637 + __name_ = (const char*)op1; 2638 + __left_ = op2; 2639 + __right_ = op3; 2640 + } 2641 + virtual size_t first_size() const 2642 + { 2643 + if (__cached_size_ == -1) 2644 + { 2645 + if (__left_) 2646 + { 2647 + __node* op1 = (__node*)__name_; 2648 + const_cast<long&>(__cached_size_) = static_cast<long>( 2649 + op1->size() + 2650 + __left_->size() + 12 + 2651 + __right_->size()); 2652 + } 2653 + else 2654 + const_cast<long&>(__cached_size_) = sizeof("operator?") - 1; 2655 + } 2656 + return static_cast<size_t>(__cached_size_); 2657 + } 2658 + virtual char* first_demangled_name(char* buf) const 2659 + { 2660 + if (__left_) 2661 + { 2662 + __node* op1 = (__node*)__name_; 2663 + *buf++ = '('; 2664 + buf = op1->get_demangled_name(buf); 2665 + strncpy(buf, ") ? (", 5); 2666 + buf += 5; 2667 + buf = __left_->get_demangled_name(buf); 2668 + strncpy(buf, ") : (", 5); 2669 + buf += 5; 2670 + buf = __right_->get_demangled_name(buf); 2671 + *buf++ = ')'; 2672 + } 2673 + else 2674 + { 2675 + strncpy(buf, "operator?", sizeof("operator?") - 1); 2676 + buf += sizeof("operator?") - 1; 2677 + } 2678 + return buf; 2679 + } 2680 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2681 + { 2682 + bool r = true; 2683 + if (__name_) 2684 + r = r && ((__node*)__name_)->fix_forward_references(t_begin, t_end); 2685 + if (__left_) 2686 + r = r && __left_->fix_forward_references(t_begin, t_end); 2687 + if (__right_) 2688 + r = r && __right_->fix_forward_references(t_begin, t_end); 2689 + return r; 2690 + } 2691 + }; 2692 + 2693 + class __operator_mod 2694 + : public __node 2695 + { 2696 + public: 2697 + 2698 + __operator_mod() {} 2699 + __operator_mod(__node* op1, __node* op2) 2700 + { 2701 + __left_ = op1; 2702 + __right_ = op2; 2703 + } 2704 + virtual size_t first_size() const 2705 + { 2706 + if (__cached_size_ == -1) 2707 + { 2708 + if (__left_) 2709 + const_cast<long&>(__cached_size_) = static_cast<long>( 2710 + __left_->size() + 7 + 2711 + __right_->size()); 2712 + else 2713 + const_cast<long&>(__cached_size_) = sizeof("operator%") - 1; 2714 + } 2715 + return static_cast<size_t>(__cached_size_); 2716 + } 2717 + virtual char* first_demangled_name(char* buf) const 2718 + { 2719 + if (__left_) 2720 + { 2721 + *buf++ = '('; 2722 + buf = __left_->get_demangled_name(buf); 2723 + strncpy(buf, ") % (", 5); 2724 + buf += 5; 2725 + buf = __right_->get_demangled_name(buf); 2726 + *buf++ = ')'; 2727 + } 2728 + else 2729 + { 2730 + strncpy(buf, "operator%", sizeof("operator%") - 1); 2731 + buf += sizeof("operator%") - 1; 2732 + } 2733 + return buf; 2734 + } 2735 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2736 + { 2737 + bool r = true; 2738 + if (__left_) 2739 + r = r && __left_->fix_forward_references(t_begin, t_end); 2740 + if (__right_) 2741 + r = r && __right_->fix_forward_references(t_begin, t_end); 2742 + return r; 2743 + } 2744 + }; 2745 + 2746 + class __operator_mod_equal 2747 + : public __node 2748 + { 2749 + public: 2750 + 2751 + __operator_mod_equal() {} 2752 + __operator_mod_equal(__node* op1, __node* op2) 2753 + { 2754 + __left_ = op1; 2755 + __right_ = op2; 2756 + } 2757 + virtual size_t first_size() const 2758 + { 2759 + if (__cached_size_ == -1) 2760 + { 2761 + if (__left_) 2762 + const_cast<long&>(__cached_size_) = static_cast<long>( 2763 + __left_->size() + 8 + 2764 + __right_->size()); 2765 + else 2766 + const_cast<long&>(__cached_size_) = sizeof("operator%=") - 1; 2767 + } 2768 + return static_cast<size_t>(__cached_size_); 2769 + } 2770 + virtual char* first_demangled_name(char* buf) const 2771 + { 2772 + if (__left_) 2773 + { 2774 + *buf++ = '('; 2775 + buf = __left_->get_demangled_name(buf); 2776 + strncpy(buf, ") %= (", 6); 2777 + buf += 6; 2778 + buf = __right_->get_demangled_name(buf); 2779 + *buf++ = ')'; 2780 + } 2781 + else 2782 + { 2783 + strncpy(buf, "operator%=", sizeof("operator%=") - 1); 2784 + buf += sizeof("operator%=") - 1; 2785 + } 2786 + return buf; 2787 + } 2788 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2789 + { 2790 + bool r = true; 2791 + if (__left_) 2792 + r = r && __left_->fix_forward_references(t_begin, t_end); 2793 + if (__right_) 2794 + r = r && __right_->fix_forward_references(t_begin, t_end); 2795 + return r; 2796 + } 2797 + }; 2798 + 2799 + class __operator_right_shift 2800 + : public __node 2801 + { 2802 + public: 2803 + 2804 + __operator_right_shift() {} 2805 + __operator_right_shift(__node* op1, __node* op2) 2806 + { 2807 + __left_ = op1; 2808 + __right_ = op2; 2809 + } 2810 + virtual size_t first_size() const 2811 + { 2812 + if (__cached_size_ == -1) 2813 + { 2814 + if (__left_) 2815 + const_cast<long&>(__cached_size_) = static_cast<long>( 2816 + __left_->size() + 8 + 2817 + __right_->size()); 2818 + else 2819 + const_cast<long&>(__cached_size_) = sizeof("operator>>") - 1; 2820 + } 2821 + return static_cast<size_t>(__cached_size_); 2822 + } 2823 + virtual char* first_demangled_name(char* buf) const 2824 + { 2825 + if (__left_) 2826 + { 2827 + *buf++ = '('; 2828 + buf = __left_->get_demangled_name(buf); 2829 + strncpy(buf, ") >> (", 6); 2830 + buf += 6; 2831 + buf = __right_->get_demangled_name(buf); 2832 + *buf++ = ')'; 2833 + } 2834 + else 2835 + { 2836 + strncpy(buf, "operator>>", sizeof("operator>>") - 1); 2837 + buf += sizeof("operator>>") - 1; 2838 + } 2839 + return buf; 2840 + } 2841 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2842 + { 2843 + bool r = true; 2844 + if (__left_) 2845 + r = r && __left_->fix_forward_references(t_begin, t_end); 2846 + if (__right_) 2847 + r = r && __right_->fix_forward_references(t_begin, t_end); 2848 + return r; 2849 + } 2850 + }; 2851 + 2852 + class __operator_right_shift_equal 2853 + : public __node 2854 + { 2855 + public: 2856 + 2857 + __operator_right_shift_equal() {} 2858 + __operator_right_shift_equal(__node* op1, __node* op2) 2859 + { 2860 + __left_ = op1; 2861 + __right_ = op2; 2862 + } 2863 + virtual size_t first_size() const 2864 + { 2865 + if (__cached_size_ == -1) 2866 + { 2867 + if (__left_) 2868 + const_cast<long&>(__cached_size_) = static_cast<long>( 2869 + __left_->size() + 9 + 2870 + __right_->size()); 2871 + else 2872 + const_cast<long&>(__cached_size_) = sizeof("operator>>=") - 1; 2873 + } 2874 + return static_cast<size_t>(__cached_size_); 2875 + } 2876 + virtual char* first_demangled_name(char* buf) const 2877 + { 2878 + if (__left_) 2879 + { 2880 + *buf++ = '('; 2881 + buf = __left_->get_demangled_name(buf); 2882 + strncpy(buf, ") >>= (", 7); 2883 + buf += 7; 2884 + buf = __right_->get_demangled_name(buf); 2885 + *buf++ = ')'; 2886 + } 2887 + else 2888 + { 2889 + strncpy(buf, "operator>>=", sizeof("operator>>=") - 1); 2890 + buf += sizeof("operator>>=") - 1; 2891 + } 2892 + return buf; 2893 + } 2894 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2895 + { 2896 + bool r = true; 2897 + if (__left_) 2898 + r = r && __left_->fix_forward_references(t_begin, t_end); 2899 + if (__right_) 2900 + r = r && __right_->fix_forward_references(t_begin, t_end); 2901 + return r; 2902 + } 2903 + }; 2904 + 2905 + class __operator_sizeof_type 2906 + : public __node 2907 + { 2908 + public: 2909 + 2910 + __operator_sizeof_type() {} 2911 + __operator_sizeof_type(__node* op) 2912 + { 2913 + __right_ = op; 2914 + } 2915 + virtual size_t first_size() const 2916 + { 2917 + if (__cached_size_ == -1) 2918 + { 2919 + if (__right_) 2920 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 9); 2921 + else 2922 + const_cast<long&>(__cached_size_) = sizeof("operator sizeof") - 1; 2923 + } 2924 + return static_cast<size_t>(__cached_size_); 2925 + } 2926 + virtual char* first_demangled_name(char* buf) const 2927 + { 2928 + if (__right_) 2929 + { 2930 + strncpy(buf, "sizeof (", 8); 2931 + buf += 8; 2932 + buf = __right_->get_demangled_name(buf); 2933 + *buf++ = ')'; 2934 + } 2935 + else 2936 + { 2937 + strncpy(buf, "operator sizeof", sizeof("operator sizeof") - 1); 2938 + buf += sizeof("operator sizeof") - 1; 2939 + } 2940 + return buf; 2941 + } 2942 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2943 + { 2944 + if (__right_) 2945 + return __right_->fix_forward_references(t_begin, t_end); 2946 + return true; 2947 + } 2948 + }; 2949 + 2950 + class __operator_sizeof_expression 2951 + : public __node 2952 + { 2953 + public: 2954 + 2955 + __operator_sizeof_expression() {} 2956 + __operator_sizeof_expression(__node* op) 2957 + { 2958 + __right_ = op; 2959 + } 2960 + virtual size_t first_size() const 2961 + { 2962 + if (__cached_size_ == -1) 2963 + { 2964 + if (__right_) 2965 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 9); 2966 + else 2967 + const_cast<long&>(__cached_size_) = sizeof("operator sizeof") - 1; 2968 + } 2969 + return static_cast<size_t>(__cached_size_); 2970 + } 2971 + virtual char* first_demangled_name(char* buf) const 2972 + { 2973 + if (__right_) 2974 + { 2975 + strncpy(buf, "sizeof (", 8); 2976 + buf += 8; 2977 + buf = __right_->get_demangled_name(buf); 2978 + *buf++ = ')'; 2979 + } 2980 + else 2981 + { 2982 + strncpy(buf, "operator sizeof", sizeof("operator sizeof") - 1); 2983 + buf += sizeof("operator sizeof") - 1; 2984 + } 2985 + return buf; 2986 + } 2987 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 2988 + { 2989 + if (__right_) 2990 + return __right_->fix_forward_references(t_begin, t_end); 2991 + return true; 2992 + } 2993 + }; 2994 + 2995 + class __typeid 2996 + : public __node 2997 + { 2998 + public: 2999 + 3000 + __typeid(__node* op) 3001 + { 3002 + __right_ = op; 3003 + } 3004 + virtual size_t first_size() const 3005 + { 3006 + if (__cached_size_ == -1) 3007 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 8); 3008 + return static_cast<size_t>(__cached_size_); 3009 + } 3010 + virtual char* first_demangled_name(char* buf) const 3011 + { 3012 + strncpy(buf, "typeid(", 7); 3013 + buf += 7; 3014 + buf = __right_->get_demangled_name(buf); 3015 + *buf++ = ')'; 3016 + return buf; 3017 + } 3018 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3019 + { 3020 + return __right_->fix_forward_references(t_begin, t_end); 3021 + } 3022 + }; 3023 + 3024 + class __throw 3025 + : public __node 3026 + { 3027 + public: 3028 + 3029 + __throw(__node* op) 3030 + { 3031 + __right_ = op; 3032 + } 3033 + virtual size_t first_size() const 3034 + { 3035 + if (__cached_size_ == -1) 3036 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 6); 3037 + return static_cast<size_t>(__cached_size_); 3038 + } 3039 + virtual char* first_demangled_name(char* buf) const 3040 + { 3041 + strncpy(buf, "throw ", 6); 3042 + return __right_->get_demangled_name(buf+6); 3043 + } 3044 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3045 + { 3046 + return __right_->fix_forward_references(t_begin, t_end); 3047 + } 3048 + }; 3049 + 3050 + class __rethrow 3051 + : public __node 3052 + { 3053 + static const ptrdiff_t n = sizeof("throw") - 1; 3054 + public: 3055 + 3056 + virtual size_t first_size() const {return n;} 3057 + virtual char* first_demangled_name(char* buf) const 3058 + { 3059 + strncpy(buf, "throw", n); 3060 + return buf+n; 3061 + } 3062 + }; 3063 + 3064 + class __operator_sizeof_param_pack 3065 + : public __node 3066 + { 3067 + public: 3068 + 3069 + __operator_sizeof_param_pack(__node* op) 3070 + { 3071 + __right_ = op; 3072 + } 3073 + virtual size_t first_size() const 3074 + { 3075 + if (__cached_size_ == -1) 3076 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->size() + 11); 3077 + return static_cast<size_t>(__cached_size_); 3078 + } 3079 + virtual char* first_demangled_name(char* buf) const 3080 + { 3081 + strncpy(buf, "sizeof...(", 10); 3082 + buf += 10; 3083 + buf = __right_->get_demangled_name(buf); 3084 + *buf++ = ')'; 3085 + return buf; 3086 + } 3087 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3088 + { 3089 + return __right_->fix_forward_references(t_begin, t_end); 3090 + } 3091 + }; 3092 + 3093 + class __const_cast 3094 + : public __node 3095 + { 3096 + public: 3097 + 3098 + __const_cast(__node* op1, __node* op2) 3099 + { 3100 + __left_ = op1; 3101 + __right_ = op2; 3102 + } 3103 + virtual size_t first_size() const 3104 + { 3105 + if (__cached_size_ == -1) 3106 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3107 + 14 + __right_->size()); 3108 + return static_cast<size_t>(__cached_size_); 3109 + } 3110 + virtual char* first_demangled_name(char* buf) const 3111 + { 3112 + strncpy(buf, "const_cast<", 11); 3113 + buf += 11; 3114 + buf = __left_->get_demangled_name(buf); 3115 + *buf++ = '>'; 3116 + *buf++ = '('; 3117 + buf = __right_->get_demangled_name(buf); 3118 + *buf++ = ')'; 3119 + return buf; 3120 + } 3121 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3122 + { 3123 + return __left_->fix_forward_references(t_begin, t_end) && 3124 + __right_->fix_forward_references(t_begin, t_end); 3125 + } 3126 + }; 3127 + 3128 + class __dynamic_cast 3129 + : public __node 3130 + { 3131 + public: 3132 + 3133 + __dynamic_cast(__node* op1, __node* op2) 3134 + { 3135 + __left_ = op1; 3136 + __right_ = op2; 3137 + } 3138 + virtual size_t first_size() const 3139 + { 3140 + if (__cached_size_ == -1) 3141 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3142 + 16 + __right_->size()); 3143 + return static_cast<size_t>(__cached_size_); 3144 + } 3145 + virtual char* first_demangled_name(char* buf) const 3146 + { 3147 + strncpy(buf, "dynamic_cast<", 13); 3148 + buf += 13; 3149 + buf = __left_->get_demangled_name(buf); 3150 + *buf++ = '>'; 3151 + *buf++ = '('; 3152 + buf = __right_->get_demangled_name(buf); 3153 + *buf++ = ')'; 3154 + return buf; 3155 + } 3156 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3157 + { 3158 + return __left_->fix_forward_references(t_begin, t_end) && 3159 + __right_->fix_forward_references(t_begin, t_end); 3160 + } 3161 + }; 3162 + 3163 + class __reinterpret_cast 3164 + : public __node 3165 + { 3166 + public: 3167 + 3168 + __reinterpret_cast(__node* op1, __node* op2) 3169 + { 3170 + __left_ = op1; 3171 + __right_ = op2; 3172 + } 3173 + virtual size_t first_size() const 3174 + { 3175 + if (__cached_size_ == -1) 3176 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3177 + 20 + __right_->size()); 3178 + return static_cast<size_t>(__cached_size_); 3179 + } 3180 + virtual char* first_demangled_name(char* buf) const 3181 + { 3182 + strncpy(buf, "reinterpret_cast<", 17); 3183 + buf += 17; 3184 + buf = __left_->get_demangled_name(buf); 3185 + *buf++ = '>'; 3186 + *buf++ = '('; 3187 + buf = __right_->get_demangled_name(buf); 3188 + *buf++ = ')'; 3189 + return buf; 3190 + } 3191 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3192 + { 3193 + return __left_->fix_forward_references(t_begin, t_end) && 3194 + __right_->fix_forward_references(t_begin, t_end); 3195 + } 3196 + }; 3197 + 3198 + class __static_cast 3199 + : public __node 3200 + { 3201 + public: 3202 + 3203 + __static_cast(__node* op1, __node* op2) 3204 + { 3205 + __left_ = op1; 3206 + __right_ = op2; 3207 + } 3208 + virtual size_t first_size() const 3209 + { 3210 + if (__cached_size_ == -1) 3211 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3212 + 15 + __right_->size()); 3213 + return static_cast<size_t>(__cached_size_); 3214 + } 3215 + virtual char* first_demangled_name(char* buf) const 3216 + { 3217 + strncpy(buf, "static_cast<", 12); 3218 + buf += 12; 3219 + buf = __left_->get_demangled_name(buf); 3220 + *buf++ = '>'; 3221 + *buf++ = '('; 3222 + buf = __right_->get_demangled_name(buf); 3223 + *buf++ = ')'; 3224 + return buf; 3225 + } 3226 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3227 + { 3228 + return __left_->fix_forward_references(t_begin, t_end) && 3229 + __right_->fix_forward_references(t_begin, t_end); 3230 + } 3231 + }; 3232 + 3233 + class __call_expr 3234 + : public __node 3235 + { 3236 + public: 3237 + 3238 + __call_expr(__node* op1, __node* op2) 3239 + { 3240 + __left_ = op1; 3241 + __right_ = op2; 3242 + } 3243 + virtual size_t first_size() const 3244 + { 3245 + if (__cached_size_ == -1) 3246 + { 3247 + size_t off = __left_->size() + 2; 3248 + if (__right_) 3249 + off += __right_->size(); 3250 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 3251 + } 3252 + return static_cast<size_t>(__cached_size_); 3253 + } 3254 + virtual char* first_demangled_name(char* buf) const 3255 + { 3256 + buf = __left_->get_demangled_name(buf); 3257 + *buf++ = '('; 3258 + if (__right_) 3259 + buf = __right_->get_demangled_name(buf); 3260 + *buf++ = ')'; 3261 + return buf; 3262 + } 3263 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3264 + { 3265 + bool r = __left_->fix_forward_references(t_begin, t_end); 3266 + if (__right_) 3267 + r = r && __right_->fix_forward_references(t_begin, t_end); 3268 + return r; 3269 + } 3270 + }; 3271 + 3272 + class __delete_array_expr 3273 + : public __node 3274 + { 3275 + public: 3276 + 3277 + __delete_array_expr(bool global, __node* op) 3278 + { 3279 + __size_ = global; 3280 + __right_ = op; 3281 + } 3282 + virtual size_t first_size() const 3283 + { 3284 + if (__cached_size_ == -1) 3285 + const_cast<long&>(__cached_size_) = static_cast<long>((__size_ ? 2 : 0) + 3286 + 9 + __right_->size()); 3287 + return static_cast<size_t>(__cached_size_); 3288 + } 3289 + virtual char* first_demangled_name(char* buf) const 3290 + { 3291 + if (__size_) 3292 + { 3293 + *buf++ = ':'; 3294 + *buf++ = ':'; 3295 + } 3296 + strncpy(buf, "delete[] ", 9); 3297 + return __right_->get_demangled_name(buf+9); 3298 + } 3299 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3300 + { 3301 + return __right_->fix_forward_references(t_begin, t_end); 3302 + } 3303 + }; 3304 + 3305 + class __delete_expr 3306 + : public __node 3307 + { 3308 + public: 3309 + 3310 + __delete_expr(bool global, __node* op) 3311 + { 3312 + __size_ = global; 3313 + __right_ = op; 3314 + } 3315 + virtual size_t first_size() const 3316 + { 3317 + if (__cached_size_ == -1) 3318 + const_cast<long&>(__cached_size_) = static_cast<long>((__size_ ? 2 : 0) + 3319 + 7 + __right_->size()); 3320 + return static_cast<size_t>(__cached_size_); 3321 + } 3322 + virtual char* first_demangled_name(char* buf) const 3323 + { 3324 + if (__size_) 3325 + { 3326 + *buf++ = ':'; 3327 + *buf++ = ':'; 3328 + } 3329 + strncpy(buf, "delete ", 7); 3330 + return __right_->get_demangled_name(buf+7); 3331 + } 3332 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3333 + { 3334 + return __right_->fix_forward_references(t_begin, t_end); 3335 + } 3336 + }; 3337 + 3338 + class __new_expr 3339 + : public __node 3340 + { 3341 + public: 3342 + 3343 + __new_expr(bool global, bool is_array, bool has_init, 3344 + __node* expr, __node* type, __node* init) 3345 + { 3346 + __size_ = (unsigned)global | 3347 + ((unsigned)is_array << 1) | 3348 + ((unsigned)has_init << 2); 3349 + __left_ = expr; 3350 + __name_ = (const char*)type; 3351 + __right_ = init; 3352 + } 3353 + virtual size_t first_size() const 3354 + { 3355 + if (__cached_size_ == -1) 3356 + { 3357 + size_t off = 4; 3358 + if (__size_ & 1) 3359 + off += 2; 3360 + if (__size_ & 2) 3361 + off += 2; 3362 + if (__left_) 3363 + { 3364 + off += 2; 3365 + off += __left_->size(); 3366 + } 3367 + __node* type = (__node*)__name_; 3368 + off += type->size(); 3369 + if (__size_ & 4) 3370 + { 3371 + off += 2; 3372 + if (__right_) 3373 + off += __right_->size(); 3374 + } 3375 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 3376 + } 3377 + return static_cast<size_t>(__cached_size_); 3378 + } 3379 + virtual char* first_demangled_name(char* buf) const 3380 + { 3381 + if (__size_ & 1) 3382 + { 3383 + *buf++ = ':'; 3384 + *buf++ = ':'; 3385 + } 3386 + *buf++ = 'n'; 3387 + *buf++ = 'e'; 3388 + *buf++ = 'w'; 3389 + if (__size_ & 2) 3390 + { 3391 + *buf++ = '['; 3392 + *buf++ = ']'; 3393 + } 3394 + if (__left_) 3395 + { 3396 + *buf++ = '('; 3397 + buf = __left_->get_demangled_name(buf); 3398 + *buf++ = ')'; 3399 + } 3400 + *buf++ = ' '; 3401 + __node* type = (__node*)__name_; 3402 + buf = type->get_demangled_name(buf); 3403 + if (__size_ & 4) 3404 + { 3405 + *buf++ = '('; 3406 + if (__right_) 3407 + buf = __right_->get_demangled_name(buf); 3408 + *buf++ = ')'; 3409 + } 3410 + return buf; 3411 + } 3412 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3413 + { 3414 + __node* type = (__node*)__name_; 3415 + bool r = type->fix_forward_references(t_begin, t_end); 3416 + if (__left_) 3417 + r = r && __left_->fix_forward_references(t_begin, t_end);; 3418 + if (__right_) 3419 + r = r && __right_->fix_forward_references(t_begin, t_end);; 3420 + return r; 3421 + } 3422 + }; 3423 + 3424 + class __dot_star_expr 3425 + : public __node 3426 + { 3427 + public: 3428 + 3429 + __dot_star_expr(__node* op1, __node* op2) 3430 + { 3431 + __left_ = op1; 3432 + __right_ = op2; 3433 + } 3434 + virtual size_t first_size() const 3435 + { 3436 + if (__cached_size_ == -1) 3437 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3438 + 2 + __right_->size()); 3439 + return static_cast<size_t>(__cached_size_); 3440 + } 3441 + virtual char* first_demangled_name(char* buf) const 3442 + { 3443 + buf = __left_->get_demangled_name(buf); 3444 + *buf++ = '.'; 3445 + *buf++ = '*'; 3446 + return __right_->get_demangled_name(buf); 3447 + } 3448 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3449 + { 3450 + return __left_->fix_forward_references(t_begin, t_end) && 3451 + __right_->fix_forward_references(t_begin, t_end); 3452 + } 3453 + }; 3454 + 3455 + class __dot_expr 3456 + : public __node 3457 + { 3458 + public: 3459 + 3460 + __dot_expr(__node* op1, __node* op2) 3461 + { 3462 + __left_ = op1; 3463 + __right_ = op2; 3464 + } 3465 + virtual size_t first_size() const 3466 + { 3467 + if (__cached_size_ == -1) 3468 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3469 + 1 + __right_->size()); 3470 + return static_cast<size_t>(__cached_size_); 3471 + } 3472 + virtual char* first_demangled_name(char* buf) const 3473 + { 3474 + buf = __left_->get_demangled_name(buf); 3475 + *buf++ = '.'; 3476 + return __right_->get_demangled_name(buf); 3477 + } 3478 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3479 + { 3480 + return __left_->fix_forward_references(t_begin, t_end) && 3481 + __right_->fix_forward_references(t_begin, t_end); 3482 + } 3483 + }; 3484 + 3485 + class __arrow_expr 3486 + : public __node 3487 + { 3488 + public: 3489 + 3490 + __arrow_expr(__node* op1, __node* op2) 3491 + { 3492 + __left_ = op1; 3493 + __right_ = op2; 3494 + } 3495 + virtual size_t first_size() const 3496 + { 3497 + if (__cached_size_ == -1) 3498 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3499 + 2 + __right_->size()); 3500 + return static_cast<size_t>(__cached_size_); 3501 + } 3502 + virtual char* first_demangled_name(char* buf) const 3503 + { 3504 + buf = __left_->get_demangled_name(buf); 3505 + *buf++ = '-'; 3506 + *buf++ = '>'; 3507 + return __right_->get_demangled_name(buf); 3508 + } 3509 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3510 + { 3511 + return __left_->fix_forward_references(t_begin, t_end) && 3512 + __right_->fix_forward_references(t_begin, t_end); 3513 + } 3514 + }; 3515 + 3516 + class __std_qualified_name 3517 + : public __node 3518 + { 3519 + static const ptrdiff_t n = sizeof("std") - 1; 3520 + public: 3521 + 3522 + __std_qualified_name() 3523 + { 3524 + } 3525 + virtual size_t first_size() const 3526 + { 3527 + return n; 3528 + } 3529 + 3530 + virtual char* first_demangled_name(char* buf) const 3531 + { 3532 + *buf++ = 's'; 3533 + *buf++ = 't'; 3534 + *buf++ = 'd'; 3535 + return buf; 3536 + } 3537 + }; 3538 + 3539 + class __sub_allocator 3540 + : public __node 3541 + { 3542 + static const ptrdiff_t n = sizeof("std::allocator") - 1; 3543 + public: 3544 + 3545 + virtual size_t first_size() const 3546 + { 3547 + return n; 3548 + } 3549 + virtual char* first_demangled_name(char* buf) const 3550 + { 3551 + strncpy(buf, "std::allocator", n); 3552 + return buf + n; 3553 + } 3554 + }; 3555 + 3556 + class __sub_basic_string 3557 + : public __node 3558 + { 3559 + static const ptrdiff_t n = sizeof("std::basic_string") - 1; 3560 + public: 3561 + 3562 + virtual size_t first_size() const 3563 + { 3564 + return n; 3565 + } 3566 + virtual char* first_demangled_name(char* buf) const 3567 + { 3568 + strncpy(buf, "std::basic_string", n); 3569 + return buf + n; 3570 + } 3571 + }; 3572 + 3573 + class __sub_string 3574 + : public __node 3575 + { 3576 + static const size_t n = sizeof("std::string") - 1; 3577 + static const size_t ne = sizeof("std::basic_string<char, std::char_traits<char>, std::allocator<char> >") - 1; 3578 + public: 3579 + 3580 + virtual size_t first_size() const 3581 + { 3582 + if (__size_) 3583 + return ne; 3584 + return n; 3585 + } 3586 + virtual char* first_demangled_name(char* buf) const 3587 + { 3588 + if (__size_) 3589 + { 3590 + strncpy(buf, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >", ne); 3591 + buf += ne; 3592 + } 3593 + else 3594 + { 3595 + strncpy(buf, "std::string", n); 3596 + buf += n; 3597 + } 3598 + return buf; 3599 + } 3600 + 3601 + virtual size_t base_size() const 3602 + { 3603 + return 12; 3604 + } 3605 + virtual char* get_base_name(char* buf) const 3606 + { 3607 + strncpy(buf, "basic_string", 12); 3608 + return buf + 12; 3609 + } 3610 + 3611 + virtual __node* base_name() const 3612 + { 3613 + const_cast<size_t&>(__size_) = true; 3614 + return const_cast<__node*>(static_cast<const __node*>(this)); 3615 + } 3616 + }; 3617 + 3618 + class __sub_istream 3619 + : public __node 3620 + { 3621 + static const ptrdiff_t n = sizeof("std::istream") - 1; 3622 + public: 3623 + 3624 + virtual size_t first_size() const {return n;} 3625 + virtual char* first_demangled_name(char* buf) const 3626 + { 3627 + strncpy(buf, "std::istream", n); 3628 + return buf + n; 3629 + } 3630 + }; 3631 + 3632 + class __sub_ostream 3633 + : public __node 3634 + { 3635 + static const ptrdiff_t n = sizeof("std::ostream") - 1; 3636 + public: 3637 + 3638 + virtual size_t first_size() const {return n;} 3639 + virtual char* first_demangled_name(char* buf) const 3640 + { 3641 + strncpy(buf, "std::ostream", n); 3642 + return buf + n; 3643 + } 3644 + }; 3645 + 3646 + class __sub_iostream 3647 + : public __node 3648 + { 3649 + static const ptrdiff_t n = sizeof("std::iostream") - 1; 3650 + public: 3651 + 3652 + virtual size_t first_size() const {return n;} 3653 + virtual char* first_demangled_name(char* buf) const 3654 + { 3655 + strncpy(buf, "std::iostream", n); 3656 + return buf + n; 3657 + } 3658 + }; 3659 + 3660 + class __sub 3661 + : public __node 3662 + { 3663 + public: 3664 + 3665 + explicit __sub(__node* arg) 3666 + { 3667 + __left_ = arg; 3668 + } 3669 + explicit __sub(size_t arg) 3670 + { 3671 + __size_ = arg; 3672 + } 3673 + virtual size_t first_size() const 3674 + { 3675 + return __left_->first_size(); 3676 + } 3677 + virtual char* first_demangled_name(char* buf) const 3678 + { 3679 + return __left_->first_demangled_name(buf); 3680 + } 3681 + virtual size_t second_size() const 3682 + { 3683 + return __left_->second_size(); 3684 + } 3685 + virtual char* second_demangled_name(char* buf) const 3686 + { 3687 + return __left_->second_demangled_name(buf); 3688 + } 3689 + virtual bool ends_with_template(bool parsing = false) const 3690 + { 3691 + return __left_->ends_with_template(parsing); 3692 + } 3693 + virtual __node* base_name() const 3694 + { 3695 + return __left_->base_name(); 3696 + } 3697 + virtual bool is_reference_or_pointer_to_function_or_array() const 3698 + { 3699 + return __left_->is_reference_or_pointer_to_function_or_array(); 3700 + } 3701 + virtual bool is_function() const 3702 + { 3703 + if (__left_ == 0) 3704 + return false; 3705 + return __left_->is_function(); 3706 + } 3707 + virtual bool is_cv_qualifer() const 3708 + { 3709 + return __left_->is_cv_qualifer(); 3710 + } 3711 + virtual bool is_ctor_dtor_conv() const 3712 + { 3713 + return __left_->is_ctor_dtor_conv(); 3714 + } 3715 + virtual bool is_array() const 3716 + { 3717 + return __left_->is_array(); 3718 + } 3719 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3720 + { 3721 + if (__left_ == 0) 3722 + { 3723 + if (__size_ < static_cast<size_t>(t_end - t_begin)) 3724 + { 3725 + __left_ = t_begin[__size_]; 3726 + __size_ = 0; 3727 + } 3728 + else 3729 + return false; 3730 + } 3731 + return true; 3732 + } 3733 + virtual size_t list_len() const 3734 + { 3735 + return __left_->list_len(); 3736 + } 3737 + virtual bool is_sub() const 3738 + { 3739 + return true; 3740 + } 3741 + }; 3742 + 3743 + class __unscoped_template_name 3744 + : public __node 3745 + { 3746 + public: 3747 + __unscoped_template_name(__node* name, __node* args) 3748 + {__left_ = name; __right_ = args;} 3749 + 3750 + virtual size_t first_size() const 3751 + { 3752 + if (__cached_size_ == -1) 3753 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3754 + __right_->size()); 3755 + return static_cast<size_t>(__cached_size_); 3756 + } 3757 + virtual char* first_demangled_name(char* buf) const 3758 + { 3759 + buf = __left_->get_demangled_name(buf); 3760 + return __right_->get_demangled_name(buf); 3761 + } 3762 + virtual bool ends_with_template(bool parsing = false) const 3763 + { 3764 + return __right_->ends_with_template(parsing); 3765 + } 3766 + virtual __node* base_name() const 3767 + { 3768 + return __left_->base_name(); 3769 + } 3770 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3771 + { 3772 + return __left_->fix_forward_references(t_begin, t_end) && 3773 + __right_->fix_forward_references(t_begin, t_end); 3774 + } 3775 + }; 3776 + 3777 + // length == 0: __left_ == NULL 3778 + // length == 1: __left_ != NULL, __right_ == NULL 3779 + // length > 1: __left_ != NULL, __right_ != NULL 3780 + class __list 3781 + : public __node 3782 + { 3783 + public: 3784 + explicit __list(__node* type) 3785 + {__left_ = type;} 3786 + 3787 + virtual size_t first_size() const 3788 + { 3789 + if (__cached_size_ == -1) 3790 + { 3791 + if (__left_ == NULL) 3792 + const_cast<long&>(__cached_size_) = 0; 3793 + else if (__right_ == NULL) 3794 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size()); 3795 + else 3796 + { 3797 + size_t off = __right_->size(); 3798 + if (off > 0) 3799 + off += 2; 3800 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + off); 3801 + } 3802 + } 3803 + return static_cast<size_t>(__cached_size_); 3804 + } 3805 + virtual char* first_demangled_name(char* buf) const 3806 + { 3807 + if (__left_ != NULL) 3808 + { 3809 + char* t = __left_->get_demangled_name(buf + (__size_ ? 2 : 0)); 3810 + if (__size_ == 0) 3811 + buf = t; 3812 + else if (t != buf+2) 3813 + { 3814 + *buf++ = ','; 3815 + *buf++ = ' '; 3816 + buf = t; 3817 + } 3818 + if (__right_) 3819 + buf = __right_->get_demangled_name(buf); 3820 + } 3821 + return buf; 3822 + } 3823 + virtual bool ends_with_template(bool parsing = false) const 3824 + { 3825 + if (__right_ != NULL) 3826 + return __right_->ends_with_template(parsing); 3827 + if (__left_ != NULL) 3828 + return __left_->ends_with_template(parsing); 3829 + return false; 3830 + } 3831 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3832 + { 3833 + bool r = true; 3834 + if (__left_) 3835 + r = r && __left_->fix_forward_references(t_begin, t_end); 3836 + if (__right_) 3837 + r = r && __right_->fix_forward_references(t_begin, t_end); 3838 + return r; 3839 + } 3840 + virtual size_t list_len() const 3841 + { 3842 + if (!__left_) 3843 + return 0; 3844 + if (!__right_) 3845 + return 1; 3846 + return 1 + __right_->list_len(); 3847 + } 3848 + }; 3849 + 3850 + class __template_args 3851 + : public __node 3852 + { 3853 + public: 3854 + __template_args(__node* name, __node* list) 3855 + { 3856 + __left_ = name; 3857 + __right_ = list; 3858 + } 3859 + 3860 + virtual size_t first_size() const 3861 + { 3862 + if (__cached_size_ == -1) 3863 + { 3864 + size_t off = 2; 3865 + if (__right_) 3866 + { 3867 + if (__right_->ends_with_template()) 3868 + ++off; 3869 + off += __right_->size(); 3870 + } 3871 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + off); 3872 + } 3873 + return static_cast<size_t>(__cached_size_); 3874 + } 3875 + virtual char* first_demangled_name(char* buf) const 3876 + { 3877 + buf = __left_->get_demangled_name(buf); 3878 + *buf++ = '<'; 3879 + if (__right_) 3880 + { 3881 + buf = __right_->get_demangled_name(buf); 3882 + if (buf[-1] == '>') 3883 + *buf++ = ' '; 3884 + } 3885 + *buf++ = '>'; 3886 + return buf; 3887 + } 3888 + virtual bool ends_with_template(bool /*parsing*/ = false) const 3889 + { 3890 + return true; 3891 + } 3892 + virtual __node* base_name() const 3893 + { 3894 + return __left_->base_name(); 3895 + } 3896 + virtual bool is_ctor_dtor_conv() const 3897 + { 3898 + return __left_->is_ctor_dtor_conv(); 3899 + } 3900 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3901 + { 3902 + bool r = __left_->fix_forward_references(t_begin, t_end); 3903 + if (__right_) 3904 + r = r && __right_->fix_forward_references(t_begin, t_end); 3905 + return r; 3906 + } 3907 + }; 3908 + 3909 + class __function_args 3910 + : public __node 3911 + { 3912 + public: 3913 + __function_args(__node* list) 3914 + {__right_ = list;} 3915 + 3916 + virtual size_t first_size() const 3917 + { 3918 + if (__cached_size_ == -1) 3919 + const_cast<long&>(__cached_size_) = static_cast<long>(2 + __right_->size()); 3920 + return static_cast<size_t>(__cached_size_); 3921 + } 3922 + virtual char* first_demangled_name(char* buf) const 3923 + { 3924 + *buf++ = '('; 3925 + buf = __right_->get_demangled_name(buf); 3926 + *buf++ = ')'; 3927 + return buf; 3928 + } 3929 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3930 + { 3931 + return __right_->fix_forward_references(t_begin, t_end); 3932 + } 3933 + }; 3934 + 3935 + class __lambda 3936 + : public __node 3937 + { 3938 + public: 3939 + __lambda(__node* params, const char *number, size_t number_size) 3940 + { 3941 + __right_ = params; 3942 + __name_ = number; 3943 + __size_ = number_size; 3944 + } 3945 + 3946 + virtual size_t first_size() const 3947 + { 3948 + if (__cached_size_ == -1) 3949 + { 3950 + size_t r = 2; 3951 + r += sizeof("'lambda'")-1; 3952 + if (__right_) 3953 + r += __right_->size(); 3954 + r += __size_; 3955 + const_cast<long&>(__cached_size_) = static_cast<long>(r); 3956 + } 3957 + return static_cast<size_t>(__cached_size_); 3958 + } 3959 + virtual char* first_demangled_name(char* buf) const 3960 + { 3961 + size_t n = sizeof("'lambda") - 1; 3962 + strncpy(buf, "'lambda", n); 3963 + buf += n; 3964 + if (__size_) 3965 + { 3966 + strncpy(buf, __name_, __size_); 3967 + buf += __size_; 3968 + } 3969 + *buf++ = '\''; 3970 + *buf++ = '('; 3971 + if (__right_) 3972 + buf = __right_->get_demangled_name(buf); 3973 + *buf++ = ')'; 3974 + return buf; 3975 + } 3976 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 3977 + { 3978 + if (__right_) 3979 + return __right_->fix_forward_references(t_begin, t_end); 3980 + return true; 3981 + } 3982 + }; 3983 + 3984 + class __unnamed 3985 + : public __node 3986 + { 3987 + public: 3988 + __unnamed(const char *number, size_t number_size) 3989 + { 3990 + __name_ = number; 3991 + __size_ = number_size; 3992 + } 3993 + 3994 + virtual size_t first_size() const 3995 + { 3996 + if (__cached_size_ == -1) 3997 + { 3998 + size_t r = 0; 3999 + r += sizeof("'unnamed'")-1; 4000 + r += __size_; 4001 + const_cast<long&>(__cached_size_) = static_cast<long>(r); 4002 + } 4003 + return static_cast<size_t>(__cached_size_); 4004 + } 4005 + virtual char* first_demangled_name(char* buf) const 4006 + { 4007 + size_t n = sizeof("'unnamed") - 1; 4008 + strncpy(buf, "'unnamed", n); 4009 + buf += n; 4010 + if (__size_) 4011 + { 4012 + strncpy(buf, __name_, __size_); 4013 + buf += __size_; 4014 + } 4015 + *buf++ = '\''; 4016 + return buf; 4017 + } 4018 + }; 4019 + 4020 + class __cv_qualifiers 4021 + : public __node 4022 + { 4023 + public: 4024 + __cv_qualifiers(size_t cv, __node* type) 4025 + { 4026 + __left_ = type; 4027 + __size_ = __left_->is_function() ? cv << 5 : cv; 4028 + } 4029 + 4030 + virtual size_t first_size() const 4031 + { 4032 + size_t s = __left_->first_size(); 4033 + if (__size_ & 4) 4034 + s += sizeof(" restrict")-1; 4035 + if (__size_ & 2) 4036 + s += sizeof(" volatile")-1; 4037 + if (__size_ & 1) 4038 + s += sizeof(" const")-1; 4039 + if (__size_ & 8) 4040 + s += sizeof(" &")-1; 4041 + if (__size_ & 16) 4042 + s += sizeof(" &&")-1; 4043 + return s; 4044 + } 4045 + virtual char* first_demangled_name(char* buf) const 4046 + { 4047 + buf = __left_->first_demangled_name(buf); 4048 + if (__size_ & 1) 4049 + { 4050 + const size_t n = sizeof(" const")-1; 4051 + strncpy(buf, " const", n); 4052 + buf += n; 4053 + } 4054 + if (__size_ & 2) 4055 + { 4056 + const size_t n = sizeof(" volatile")-1; 4057 + strncpy(buf, " volatile", n); 4058 + buf += n; 4059 + } 4060 + if (__size_ & 4) 4061 + { 4062 + const size_t n = sizeof(" restrict")-1; 4063 + strncpy(buf, " restrict", n); 4064 + buf += n; 4065 + } 4066 + if (__size_ & 8) 4067 + { 4068 + *buf++ = ' '; 4069 + *buf++ = '&'; 4070 + } 4071 + if (__size_ & 16) 4072 + { 4073 + *buf++ = ' '; 4074 + *buf++ = '&'; 4075 + *buf++ = '&'; 4076 + } 4077 + return buf; 4078 + } 4079 + virtual size_t second_size() const 4080 + { 4081 + size_t s = __left_->second_size(); 4082 + if (__size_ & 128) 4083 + s += sizeof(" restrict")-1; 4084 + if (__size_ & 64) 4085 + s += sizeof(" volatile")-1; 4086 + if (__size_ & 32) 4087 + s += sizeof(" const")-1; 4088 + if (__size_ & 256) 4089 + s += sizeof(" &")-1; 4090 + if (__size_ & 512) 4091 + s += sizeof(" &&")-1; 4092 + return s; 4093 + } 4094 + virtual char* second_demangled_name(char* buf) const 4095 + { 4096 + buf = __left_->second_demangled_name(buf); 4097 + if (__size_ & 32) 4098 + { 4099 + const size_t n = sizeof(" const")-1; 4100 + strncpy(buf, " const", n); 4101 + buf += n; 4102 + } 4103 + if (__size_ & 64) 4104 + { 4105 + const size_t n = sizeof(" volatile")-1; 4106 + strncpy(buf, " volatile", n); 4107 + buf += n; 4108 + } 4109 + if (__size_ & 128) 4110 + { 4111 + const size_t n = sizeof(" restrict")-1; 4112 + strncpy(buf, " restrict", n); 4113 + buf += n; 4114 + } 4115 + if (__size_ & 256) 4116 + { 4117 + *buf++ = ' '; 4118 + *buf++ = '&'; 4119 + } 4120 + if (__size_ & 512) 4121 + { 4122 + *buf++ = ' '; 4123 + *buf++ = '&'; 4124 + *buf++ = '&'; 4125 + } 4126 + return buf; 4127 + } 4128 + virtual __node* base_name() const 4129 + { 4130 + return __left_->base_name(); 4131 + } 4132 + virtual bool is_reference_or_pointer_to_function_or_array() const 4133 + { 4134 + return __left_->is_reference_or_pointer_to_function_or_array(); 4135 + } 4136 + virtual bool is_function() const 4137 + { 4138 + return __left_->is_function(); 4139 + } 4140 + virtual bool is_cv_qualifer() const 4141 + { 4142 + return true; 4143 + } 4144 + virtual __node* extract_cv(__node*& rt) const 4145 + { 4146 + if (rt == this) 4147 + { 4148 + rt = __left_; 4149 + return const_cast<__node*>(static_cast<const __node*>(this)); 4150 + } 4151 + return 0; 4152 + } 4153 + virtual bool ends_with_template(bool parsing = false) const 4154 + { 4155 + if (parsing) 4156 + return __left_->ends_with_template(parsing); 4157 + return false; 4158 + } 4159 + virtual bool is_ctor_dtor_conv() const 4160 + { 4161 + return __left_->is_ctor_dtor_conv(); 4162 + } 4163 + virtual bool is_array() const 4164 + { 4165 + return __left_->is_array(); 4166 + } 4167 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4168 + { 4169 + return __left_->fix_forward_references(t_begin, t_end); 4170 + } 4171 + virtual size_t list_len() const 4172 + { 4173 + return __left_->list_len(); 4174 + } 4175 + }; 4176 + 4177 + class __extended_qualifier 4178 + : public __node 4179 + { 4180 + public: 4181 + __extended_qualifier(__node* name, __node* type) 4182 + { 4183 + __left_ = type; 4184 + __right_ = name; 4185 + __size_ = __left_->is_function() ? 1 : 0; 4186 + } 4187 + 4188 + virtual size_t first_size() const 4189 + { 4190 + size_t s = __left_->first_size(); 4191 + if (__size_ == 0) 4192 + s += __right_->size() + 1; 4193 + return s; 4194 + } 4195 + virtual char* first_demangled_name(char* buf) const 4196 + { 4197 + buf = __left_->first_demangled_name(buf); 4198 + if (__size_ == 0) 4199 + { 4200 + *buf++ = ' '; 4201 + buf = __right_->get_demangled_name(buf); 4202 + } 4203 + return buf; 4204 + } 4205 + virtual size_t second_size() const 4206 + { 4207 + size_t s = __left_->second_size(); 4208 + if (__size_ == 1) 4209 + s += __right_->size() + 1; 4210 + return s; 4211 + } 4212 + virtual char* second_demangled_name(char* buf) const 4213 + { 4214 + buf = __left_->second_demangled_name(buf); 4215 + if (__size_ == 1) 4216 + { 4217 + *buf++ = ' '; 4218 + buf = __right_->get_demangled_name(buf); 4219 + } 4220 + return buf; 4221 + } 4222 + virtual __node* base_name() const 4223 + { 4224 + return __left_->base_name(); 4225 + } 4226 + virtual bool is_reference_or_pointer_to_function_or_array() const 4227 + { 4228 + return __left_->is_reference_or_pointer_to_function_or_array(); 4229 + } 4230 + virtual bool is_function() const 4231 + { 4232 + return __left_->is_function(); 4233 + } 4234 + virtual bool is_cv_qualifer() const 4235 + { 4236 + return true; 4237 + } 4238 + virtual __node* extract_cv(__node*& rt) const 4239 + { 4240 + if (rt == this) 4241 + { 4242 + rt = __left_; 4243 + return const_cast<__node*>(static_cast<const __node*>(this)); 4244 + } 4245 + return 0; 4246 + } 4247 + virtual bool ends_with_template(bool parsing = false) const 4248 + { 4249 + return __left_->ends_with_template(parsing); 4250 + } 4251 + virtual bool is_ctor_dtor_conv() const 4252 + { 4253 + return __left_->is_ctor_dtor_conv(); 4254 + } 4255 + virtual bool is_array() const 4256 + { 4257 + return __left_->is_array(); 4258 + } 4259 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4260 + { 4261 + return __left_->fix_forward_references(t_begin, t_end); 4262 + } 4263 + virtual size_t list_len() const 4264 + { 4265 + return __left_->list_len(); 4266 + } 4267 + }; 4268 + 4269 + class __function 4270 + : public __node 4271 + { 4272 + public: 4273 + 4274 + __function(__node* name, __node* signature, size_t ret_goes_first = true) 4275 + { 4276 + __size_ = ret_goes_first; 4277 + __left_ = name; 4278 + __right_ = signature; 4279 + } 4280 + 4281 + virtual size_t first_size() const 4282 + { 4283 + size_t off = 0; 4284 + if (__size_) 4285 + { 4286 + off = __right_->first_size(); 4287 + if (off > 0 && (__left_ == NULL || 4288 + !__right_->__left_->is_reference_or_pointer_to_function_or_array())) 4289 + ++off; 4290 + } 4291 + else 4292 + off = 5; 4293 + if (__left_) 4294 + off += __left_->first_size(); 4295 + else 4296 + ++off; 4297 + return off; 4298 + } 4299 + 4300 + virtual size_t second_size() const 4301 + { 4302 + size_t off = 0; 4303 + if (__left_ == NULL) 4304 + off = 1; 4305 + off += __right_->second_size(); 4306 + if (!__size_) 4307 + { 4308 + off += 2; 4309 + off += __right_->first_size(); 4310 + } 4311 + return off; 4312 + } 4313 + 4314 + virtual char* first_demangled_name(char* buf) const 4315 + { 4316 + if (__size_) 4317 + { 4318 + const char* t = buf; 4319 + buf = __right_->first_demangled_name(buf); 4320 + if (buf != t && (__left_ == NULL || 4321 + !__right_->__left_->is_reference_or_pointer_to_function_or_array())) 4322 + *buf++ = ' '; 4323 + } 4324 + else 4325 + { 4326 + strncpy(buf, "auto ", 5); 4327 + buf += 5; 4328 + } 4329 + if (__left_) 4330 + buf = __left_->first_demangled_name(buf); 4331 + else 4332 + *buf++ = '('; 4333 + return buf; 4334 + } 4335 + virtual char* second_demangled_name(char* buf) const 4336 + { 4337 + if (__left_ == NULL) 4338 + *buf++ = ')'; 4339 + buf = __right_->second_demangled_name(buf); 4340 + if (!__size_) 4341 + { 4342 + *buf++ = '-'; 4343 + *buf++ = '>'; 4344 + buf = __right_->first_demangled_name(buf); 4345 + } 4346 + return buf; 4347 + } 4348 + virtual char* get_demangled_name(char* buf) const 4349 + { 4350 + if (__size_) 4351 + { 4352 + const char* t = buf; 4353 + buf = __right_->first_demangled_name(buf); 4354 + if (buf != t && (__left_ == NULL || 4355 + !__right_->__left_->is_reference_or_pointer_to_function_or_array())) 4356 + *buf++ = ' '; 4357 + } 4358 + else 4359 + { 4360 + strncpy(buf, "auto ", 5); 4361 + buf += 5; 4362 + } 4363 + if (__left_) 4364 + buf = __left_->first_demangled_name(buf); 4365 + buf = __right_->second_demangled_name(buf); 4366 + if (!__size_) 4367 + { 4368 + *buf++ = '-'; 4369 + *buf++ = '>'; 4370 + buf = __right_->first_demangled_name(buf); 4371 + } 4372 + return buf; 4373 + } 4374 + 4375 + virtual size_t size() const 4376 + { 4377 + if (__cached_size_ == -1) 4378 + { 4379 + size_t off = 0; 4380 + if (__size_) 4381 + { 4382 + off = __right_->first_size(); 4383 + if (off > 0 && (__left_ == NULL || 4384 + !__right_->__left_->is_reference_or_pointer_to_function_or_array())) 4385 + ++off; 4386 + } 4387 + else 4388 + off = 5; 4389 + if (__left_) 4390 + off += __left_->first_size(); 4391 + off += __right_->second_size(); 4392 + if (!__size_) 4393 + { 4394 + off += 2; 4395 + off += __right_->first_size(); 4396 + } 4397 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 4398 + } 4399 + return static_cast<size_t>(__cached_size_); 4400 + } 4401 + 4402 + virtual bool is_function() const 4403 + { 4404 + return true; 4405 + } 4406 + virtual bool is_ctor_dtor_conv() const 4407 + { 4408 + return __left_->is_ctor_dtor_conv(); 4409 + } 4410 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4411 + { 4412 + bool r = true; 4413 + if (__left_) 4414 + r = r && __left_->fix_forward_references(t_begin, t_end); 4415 + r = r && __right_->fix_forward_references(t_begin, t_end); 4416 + return r; 4417 + } 4418 + }; 4419 + 4420 + class __function_signature 4421 + : public __node 4422 + { 4423 + public: 4424 + __function_signature(__node* ret, __node* args) 4425 + { 4426 + __left_ = ret; 4427 + __right_ = args; 4428 + } 4429 + virtual size_t first_size() const 4430 + { 4431 + return __left_ ? __left_->first_size() : 0; 4432 + } 4433 + 4434 + virtual size_t second_size() const 4435 + { 4436 + return 2 + (__right_ ? __right_->size() : 0) 4437 + + (__left_ ? __left_->second_size() : 0); 4438 + } 4439 + 4440 + virtual char* first_demangled_name(char* buf) const 4441 + { 4442 + if (__left_) 4443 + buf = __left_->first_demangled_name(buf); 4444 + return buf; 4445 + } 4446 + 4447 + virtual char* second_demangled_name(char* buf) const 4448 + { 4449 + *buf++ = '('; 4450 + if (__right_) 4451 + buf = __right_->get_demangled_name(buf); 4452 + *buf++ = ')'; 4453 + if (__left_) 4454 + buf = __left_->second_demangled_name(buf); 4455 + return buf; 4456 + } 4457 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4458 + { 4459 + bool r = true; 4460 + if (__left_) 4461 + r = r && __left_->fix_forward_references(t_begin, t_end); 4462 + if (__right_) 4463 + r = r && __right_->fix_forward_references(t_begin, t_end); 4464 + return r; 4465 + } 4466 + }; 4467 + 4468 + class __pointer_to 4469 + : public __node 4470 + { 4471 + public: 4472 + 4473 + explicit __pointer_to(__node* type) 4474 + { 4475 + __left_ = type; 4476 + } 4477 + virtual size_t first_size() const 4478 + { 4479 + return __left_->first_size() + (__left_->is_array() ? 3 : 1); 4480 + } 4481 + virtual size_t second_size() const 4482 + { 4483 + return __left_->second_size() + (__left_->is_array() ? 1 : 0); 4484 + } 4485 + virtual char* first_demangled_name(char* buf) const 4486 + { 4487 + buf = __left_->first_demangled_name(buf); 4488 + if (__left_->is_array()) 4489 + { 4490 + *buf++ = ' '; 4491 + *buf++ = '('; 4492 + *buf++ = '*'; 4493 + } 4494 + else 4495 + *buf++ = '*'; 4496 + return buf; 4497 + } 4498 + virtual char* second_demangled_name(char* buf) const 4499 + { 4500 + if (__left_->is_array()) 4501 + *buf++ = ')'; 4502 + return __left_->second_demangled_name(buf); 4503 + } 4504 + virtual __node* base_name() const 4505 + { 4506 + return __left_->base_name(); 4507 + } 4508 + virtual bool is_reference_or_pointer_to_function_or_array() const 4509 + { 4510 + return __left_->is_function() || 4511 + __left_->is_reference_or_pointer_to_function_or_array(); 4512 + } 4513 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4514 + { 4515 + return __left_->fix_forward_references(t_begin, t_end); 4516 + } 4517 + virtual size_t list_len() const 4518 + { 4519 + return __left_->list_len(); 4520 + } 4521 + }; 4522 + 4523 + class __lvalue_reference_to 4524 + : public __node 4525 + { 4526 + public: 4527 + 4528 + explicit __lvalue_reference_to(__node* type) 4529 + { 4530 + __left_ = type; 4531 + } 4532 + virtual size_t first_size() const 4533 + { 4534 + return __left_->first_size() + (__left_->is_array() ? 3 : 1); 4535 + } 4536 + virtual size_t second_size() const 4537 + { 4538 + return __left_->second_size() + (__left_->is_array() ? 1 : 0); 4539 + } 4540 + virtual char* first_demangled_name(char* buf) const 4541 + { 4542 + buf = __left_->first_demangled_name(buf); 4543 + if (__left_->is_array()) 4544 + { 4545 + *buf++ = ' '; 4546 + *buf++ = '('; 4547 + *buf++ = '&'; 4548 + } 4549 + else 4550 + *buf++ = '&'; 4551 + return buf; 4552 + } 4553 + virtual char* second_demangled_name(char* buf) const 4554 + { 4555 + if (__left_->is_array()) 4556 + *buf++ = ')'; 4557 + return __left_->second_demangled_name(buf); 4558 + } 4559 + virtual __node* base_name() const 4560 + { 4561 + return __left_->base_name(); 4562 + } 4563 + virtual bool is_reference_or_pointer_to_function_or_array() const 4564 + { 4565 + return __left_->is_function(); 4566 + } 4567 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4568 + { 4569 + return __left_->fix_forward_references(t_begin, t_end); 4570 + } 4571 + virtual size_t list_len() const 4572 + { 4573 + return __left_->list_len(); 4574 + } 4575 + }; 4576 + 4577 + class __rvalue_reference_to 4578 + : public __node 4579 + { 4580 + public: 4581 + 4582 + explicit __rvalue_reference_to(__node* type) 4583 + { 4584 + __left_ = type; 4585 + } 4586 + virtual size_t first_size() const 4587 + { 4588 + return __left_->first_size() + (__left_->is_array() ? 4 : 2); 4589 + } 4590 + virtual size_t second_size() const 4591 + { 4592 + return __left_->second_size() + (__left_->is_array() ? 1 : 0); 4593 + } 4594 + virtual char* first_demangled_name(char* buf) const 4595 + { 4596 + buf = __left_->first_demangled_name(buf); 4597 + if (__left_->is_array()) 4598 + { 4599 + strncpy(buf, " (&&", 4); 4600 + buf += 4; 4601 + } 4602 + else 4603 + { 4604 + *buf++ = '&'; 4605 + *buf++ = '&'; 4606 + } 4607 + return buf; 4608 + } 4609 + virtual char* second_demangled_name(char* buf) const 4610 + { 4611 + if (__left_->is_array()) 4612 + *buf++ = ')'; 4613 + return __left_->second_demangled_name(buf); 4614 + } 4615 + virtual __node* base_name() const 4616 + { 4617 + return __left_->base_name(); 4618 + } 4619 + virtual bool is_reference_or_pointer_to_function_or_array() const 4620 + { 4621 + return __left_->is_function(); 4622 + } 4623 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4624 + { 4625 + return __left_->fix_forward_references(t_begin, t_end); 4626 + } 4627 + virtual size_t list_len() const 4628 + { 4629 + return __left_->list_len(); 4630 + } 4631 + }; 4632 + 4633 + class __d_complex 4634 + : public __node 4635 + { 4636 + static const size_t n = sizeof(" complex") - 1; 4637 + public: 4638 + 4639 + explicit __d_complex(__node* type) 4640 + { 4641 + __left_ = type; 4642 + } 4643 + virtual size_t first_size() const 4644 + { 4645 + if (__cached_size_ == -1) 4646 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __left_->size()); 4647 + return static_cast<size_t>(__cached_size_); 4648 + } 4649 + virtual char* first_demangled_name(char* buf) const 4650 + { 4651 + buf = __left_->get_demangled_name(buf); 4652 + strncpy(buf, " complex", n); 4653 + return buf + n; 4654 + } 4655 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4656 + { 4657 + return __left_->fix_forward_references(t_begin, t_end); 4658 + } 4659 + }; 4660 + 4661 + class __imaginary 4662 + : public __node 4663 + { 4664 + static const size_t n = sizeof(" imaginary") - 1; 4665 + public: 4666 + 4667 + explicit __imaginary(__node* type) 4668 + { 4669 + __left_ = type; 4670 + } 4671 + virtual size_t first_size() const 4672 + { 4673 + if (__cached_size_ == -1) 4674 + const_cast<long&>(__cached_size_) = static_cast<long>(n + __left_->size()); 4675 + return static_cast<size_t>(__cached_size_); 4676 + } 4677 + virtual char* first_demangled_name(char* buf) const 4678 + { 4679 + buf = __left_->get_demangled_name(buf); 4680 + strncpy(buf, " imaginary", n); 4681 + return buf + n; 4682 + } 4683 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4684 + { 4685 + return __left_->fix_forward_references(t_begin, t_end); 4686 + } 4687 + }; 4688 + 4689 + class __pack_expansion 4690 + : public __node 4691 + { 4692 + public: 4693 + 4694 + explicit __pack_expansion(__node* type) 4695 + { 4696 + __left_ = type; 4697 + } 4698 + virtual size_t first_size() const 4699 + { 4700 + if (__cached_size_ == -1) 4701 + { 4702 + size_t len = __left_->list_len(); 4703 + size_t off = 0; 4704 + if (len != 0) 4705 + { 4706 + if (__left_->is_sub() || len == 1) 4707 + off = __left_->size(); 4708 + else 4709 + { 4710 + __node* top = __left_; 4711 + __node* bottom = top; 4712 + while (!bottom->__left_->is_sub()) 4713 + bottom = bottom->__left_; 4714 + __node* sub = bottom->__left_; 4715 + __node* i = sub->__left_; 4716 + bool first = true; 4717 + top->reset_cached_size(); 4718 + while (i) 4719 + { 4720 + if (!first) 4721 + off += 2; 4722 + bottom->__left_ = i->__left_; 4723 + off += top->size(); 4724 + top->reset_cached_size(); 4725 + i = i->__right_; 4726 + first = false; 4727 + } 4728 + bottom->__left_ = sub; 4729 + } 4730 + } 4731 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 4732 + } 4733 + return static_cast<size_t>(__cached_size_); 4734 + } 4735 + virtual char* first_demangled_name(char* buf) const 4736 + { 4737 + size_t len = __left_->list_len(); 4738 + if (len != 0) 4739 + { 4740 + if (__left_->is_sub() || len == 1) 4741 + buf = __left_->get_demangled_name(buf); 4742 + else 4743 + { 4744 + __node* top = __left_; 4745 + __node* bottom = top; 4746 + while (!bottom->__left_->is_sub()) 4747 + bottom = bottom->__left_; 4748 + __node* sub = bottom->__left_; 4749 + __node* i = sub->__left_; 4750 + bool first = true; 4751 + top->reset_cached_size(); 4752 + while (i) 4753 + { 4754 + if (!first) 4755 + { 4756 + *buf++ = ','; 4757 + *buf++ = ' '; 4758 + } 4759 + bottom->__left_ = i->__left_; 4760 + buf = top->get_demangled_name(buf); 4761 + top->reset_cached_size(); 4762 + i = i->__right_; 4763 + first = false; 4764 + } 4765 + bottom->__left_ = sub; 4766 + } 4767 + } 4768 + return buf; 4769 + } 4770 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 4771 + { 4772 + return __left_->fix_forward_references(t_begin, t_end); 4773 + } 4774 + }; 4775 + 4776 + class __void 4777 + : public __node 4778 + { 4779 + static const size_t n = sizeof("void") - 1; 4780 + public: 4781 + 4782 + virtual size_t first_size() const {return n;} 4783 + virtual char* first_demangled_name(char* buf) const 4784 + { 4785 + strncpy(buf, "void", n); 4786 + return buf + n; 4787 + } 4788 + }; 4789 + 4790 + class __wchar_t 4791 + : public __node 4792 + { 4793 + static const size_t n = sizeof("wchar_t") - 1; 4794 + public: 4795 + 4796 + virtual size_t first_size() const {return n;} 4797 + virtual char* first_demangled_name(char* buf) const 4798 + { 4799 + strncpy(buf, "wchar_t", n); 4800 + return buf + n; 4801 + } 4802 + }; 4803 + 4804 + class __wchar_t_literal 4805 + : public __node 4806 + { 4807 + public: 4808 + explicit __wchar_t_literal(const char* __first, const char* __last) 4809 + { 4810 + __name_ = __first; 4811 + __size_ = static_cast<size_t>(__last - __first); 4812 + } 4813 + 4814 + virtual size_t first_size() const 4815 + { 4816 + return __size_+9; 4817 + } 4818 + virtual char* first_demangled_name(char* buf) const 4819 + { 4820 + strncpy(buf, "(wchar_t)", 9); 4821 + buf += 9; 4822 + strncpy(buf, __name_, __size_); 4823 + return buf + __size_; 4824 + } 4825 + }; 4826 + 4827 + class __bool 4828 + : public __node 4829 + { 4830 + static const size_t n = sizeof("bool") - 1; 4831 + public: 4832 + 4833 + virtual size_t first_size() const {return n;} 4834 + virtual char* first_demangled_name(char* buf) const 4835 + { 4836 + strncpy(buf, "bool", n); 4837 + return buf + n; 4838 + } 4839 + }; 4840 + 4841 + class __bool_literal 4842 + : public __node 4843 + { 4844 + public: 4845 + explicit __bool_literal(const char* __name, unsigned __size) 4846 + { 4847 + __name_ = __name; 4848 + __size_ = __size; 4849 + } 4850 + 4851 + virtual size_t first_size() const 4852 + { 4853 + return __size_; 4854 + } 4855 + virtual char* first_demangled_name(char* buf) const 4856 + { 4857 + strncpy(buf, __name_, __size_); 4858 + return buf + __size_; 4859 + } 4860 + }; 4861 + 4862 + class __char 4863 + : public __node 4864 + { 4865 + static const size_t n = sizeof("char") - 1; 4866 + public: 4867 + 4868 + virtual size_t first_size() const {return n;} 4869 + virtual char* first_demangled_name(char* buf) const 4870 + { 4871 + strncpy(buf, "char", n); 4872 + return buf + n; 4873 + } 4874 + }; 4875 + 4876 + class __char_literal 4877 + : public __node 4878 + { 4879 + public: 4880 + explicit __char_literal(const char* __first, const char* __last) 4881 + { 4882 + __name_ = __first; 4883 + __size_ = static_cast<size_t>(__last - __first); 4884 + } 4885 + 4886 + virtual size_t first_size() const 4887 + { 4888 + return __size_+6; 4889 + } 4890 + virtual char* first_demangled_name(char* buf) const 4891 + { 4892 + strncpy(buf, "(char)", 6); 4893 + buf += 6; 4894 + if (*__name_ == 'n') 4895 + { 4896 + *buf++ = '-'; // strncpy(buf+6, "-", 1); 4897 + strncpy(buf, __name_+1, __size_-1); 4898 + buf += __size_ - 1; 4899 + } 4900 + else 4901 + { 4902 + strncpy(buf, __name_, __size_); 4903 + buf += __size_; 4904 + } 4905 + return buf; 4906 + } 4907 + }; 4908 + 4909 + class __signed_char 4910 + : public __node 4911 + { 4912 + static const size_t n = sizeof("signed char") - 1; 4913 + public: 4914 + 4915 + virtual size_t first_size() const {return n;} 4916 + virtual char* first_demangled_name(char* buf) const 4917 + { 4918 + strncpy(buf, "signed char", n); 4919 + return buf + n; 4920 + } 4921 + }; 4922 + 4923 + class __signed_char_literal 4924 + : public __node 4925 + { 4926 + public: 4927 + explicit __signed_char_literal(const char* __first, const char* __last) 4928 + { 4929 + __name_ = __first; 4930 + __size_ = static_cast<size_t>(__last - __first); 4931 + } 4932 + 4933 + virtual size_t first_size() const 4934 + { 4935 + return __size_+13; 4936 + } 4937 + virtual char* first_demangled_name(char* buf) const 4938 + { 4939 + strncpy(buf, "(signed char)", 13); 4940 + buf += 13; 4941 + if (*__name_ == 'n') 4942 + { 4943 + *buf++ = '-'; 4944 + strncpy(buf, __name_+1, __size_-1); 4945 + buf += __size_ - 1; 4946 + } 4947 + else 4948 + { 4949 + strncpy(buf, __name_, __size_); 4950 + buf += __size_; 4951 + } 4952 + return buf; 4953 + } 4954 + }; 4955 + 4956 + class __unsigned_char 4957 + : public __node 4958 + { 4959 + static const size_t n = sizeof("unsigned char") - 1; 4960 + public: 4961 + 4962 + virtual size_t first_size() const {return n;} 4963 + virtual char* first_demangled_name(char* buf) const 4964 + { 4965 + strncpy(buf, "unsigned char", n); 4966 + return buf + n; 4967 + } 4968 + }; 4969 + 4970 + class __unsigned_char_literal 4971 + : public __node 4972 + { 4973 + public: 4974 + explicit __unsigned_char_literal(const char* __first, const char* __last) 4975 + { 4976 + __name_ = __first; 4977 + __size_ = static_cast<size_t>(__last - __first); 4978 + } 4979 + 4980 + virtual size_t first_size() const 4981 + { 4982 + return __size_+15; 4983 + } 4984 + virtual char* first_demangled_name(char* buf) const 4985 + { 4986 + strncpy(buf, "(unsigned char)", 15); 4987 + buf += 15; 4988 + strncpy(buf, __name_, __size_); 4989 + return buf + __size_; 4990 + } 4991 + }; 4992 + 4993 + class __short 4994 + : public __node 4995 + { 4996 + static const size_t n = sizeof("short") - 1; 4997 + public: 4998 + 4999 + virtual size_t first_size() const {return n;} 5000 + virtual char* first_demangled_name(char* buf) const 5001 + { 5002 + strncpy(buf, "short", n); 5003 + return buf + n; 5004 + } 5005 + }; 5006 + 5007 + class __short_literal 5008 + : public __node 5009 + { 5010 + public: 5011 + explicit __short_literal(const char* __first, const char* __last) 5012 + { 5013 + __name_ = __first; 5014 + __size_ = static_cast<size_t>(__last - __first); 5015 + } 5016 + 5017 + virtual size_t first_size() const 5018 + { 5019 + return __size_+7; 5020 + } 5021 + virtual char* first_demangled_name(char* buf) const 5022 + { 5023 + strncpy(buf, "(short)", 7); 5024 + buf += 7; 5025 + if (*__name_ == 'n') 5026 + { 5027 + *buf++ = '-'; 5028 + strncpy(buf, __name_+1, __size_-1); 5029 + buf += __size_ - 1; 5030 + } 5031 + else 5032 + { 5033 + strncpy(buf, __name_, __size_); 5034 + buf += __size_; 5035 + } 5036 + return buf; 5037 + } 5038 + }; 5039 + 5040 + class __unsigned_short 5041 + : public __node 5042 + { 5043 + static const size_t n = sizeof("unsigned short") - 1; 5044 + public: 5045 + 5046 + virtual size_t first_size() const {return n;} 5047 + virtual char* first_demangled_name(char* buf) const 5048 + { 5049 + strncpy(buf, "unsigned short", n); 5050 + return buf + n; 5051 + } 5052 + }; 5053 + 5054 + class __unsigned_short_literal 5055 + : public __node 5056 + { 5057 + public: 5058 + explicit __unsigned_short_literal(const char* __first, const char* __last) 5059 + { 5060 + __name_ = __first; 5061 + __size_ = static_cast<size_t>(__last - __first); 5062 + } 5063 + 5064 + virtual size_t first_size() const 5065 + { 5066 + return __size_+16; 5067 + } 5068 + virtual char* first_demangled_name(char* buf) const 5069 + { 5070 + strncpy(buf, "(unsigned short)", 16); 5071 + buf += 16; 5072 + strncpy(buf, __name_, __size_); 5073 + return buf + __size_; 5074 + } 5075 + }; 5076 + 5077 + class __int 5078 + : public __node 5079 + { 5080 + static const size_t n = sizeof("int") - 1; 5081 + public: 5082 + 5083 + virtual size_t first_size() const {return n;} 5084 + virtual char* first_demangled_name(char* buf) const 5085 + { 5086 + *buf++ = 'i'; 5087 + *buf++ = 'n'; 5088 + *buf++ = 't'; 5089 + return buf; 5090 + } 5091 + }; 5092 + 5093 + class __int_literal 5094 + : public __node 5095 + { 5096 + public: 5097 + explicit __int_literal(const char* __first, const char* __last) 5098 + { 5099 + __name_ = __first; 5100 + __size_ = static_cast<size_t>(__last - __first); 5101 + } 5102 + 5103 + virtual size_t first_size() const 5104 + { 5105 + return __size_; 5106 + } 5107 + virtual char* first_demangled_name(char* buf) const 5108 + { 5109 + if (*__name_ == 'n') 5110 + { 5111 + *buf++ = '-'; 5112 + strncpy(buf, __name_+1, __size_-1); 5113 + buf += __size_ - 1; 5114 + } 5115 + else 5116 + { 5117 + strncpy(buf, __name_, __size_); 5118 + buf += __size_; 5119 + } 5120 + return buf; 5121 + } 5122 + }; 5123 + 5124 + class __unsigned_int 5125 + : public __node 5126 + { 5127 + static const size_t n = sizeof("unsigned int") - 1; 5128 + public: 5129 + 5130 + virtual size_t first_size() const {return n;} 5131 + virtual char* first_demangled_name(char* buf) const 5132 + { 5133 + strncpy(buf, "unsigned int", n); 5134 + return buf + n; 5135 + } 5136 + }; 5137 + 5138 + class __unsigned_int_literal 5139 + : public __node 5140 + { 5141 + public: 5142 + explicit __unsigned_int_literal(const char* __first, const char* __last) 5143 + { 5144 + __name_ = __first; 5145 + __size_ = static_cast<size_t>(__last - __first); 5146 + } 5147 + 5148 + virtual size_t first_size() const 5149 + { 5150 + return __size_+1; 5151 + } 5152 + virtual char* first_demangled_name(char* buf) const 5153 + { 5154 + strncpy(buf, __name_, __size_); 5155 + buf += __size_; 5156 + *buf++ = 'u'; 5157 + return buf; 5158 + } 5159 + }; 5160 + 5161 + class __long 5162 + : public __node 5163 + { 5164 + static const size_t n = sizeof("long") - 1; 5165 + public: 5166 + 5167 + virtual size_t first_size() const {return n;} 5168 + virtual char* first_demangled_name(char* buf) const 5169 + { 5170 + strncpy(buf, "long", n); 5171 + return buf + n; 5172 + } 5173 + }; 5174 + 5175 + class __long_literal 5176 + : public __node 5177 + { 5178 + public: 5179 + explicit __long_literal(const char* __first, const char* __last) 5180 + { 5181 + __name_ = __first; 5182 + __size_ = static_cast<size_t>(__last - __first); 5183 + } 5184 + 5185 + virtual size_t first_size() const 5186 + { 5187 + return __size_+1; 5188 + } 5189 + virtual char* first_demangled_name(char* buf) const 5190 + { 5191 + if (*__name_ == 'n') 5192 + { 5193 + *buf++ = '-'; // strncpy(buf, "-", 1); 5194 + strncpy(buf, __name_+1, __size_-1); 5195 + buf += __size_ - 1; 5196 + } 5197 + else 5198 + { 5199 + strncpy(buf, __name_, __size_); 5200 + buf += __size_; 5201 + } 5202 + *buf++ = 'l'; 5203 + return buf; 5204 + } 5205 + }; 5206 + 5207 + class __unsigned_long 5208 + : public __node 5209 + { 5210 + static const size_t n = sizeof("unsigned long") - 1; 5211 + public: 5212 + 5213 + virtual size_t first_size() const {return n;} 5214 + virtual char* first_demangled_name(char* buf) const 5215 + { 5216 + strncpy(buf, "unsigned long", n); 5217 + return buf + n; 5218 + } 5219 + }; 5220 + 5221 + class __unsigned_long_literal 5222 + : public __node 5223 + { 5224 + public: 5225 + explicit __unsigned_long_literal(const char* __first, const char* __last) 5226 + { 5227 + __name_ = __first; 5228 + __size_ = static_cast<size_t>(__last - __first); 5229 + } 5230 + 5231 + virtual size_t first_size() const 5232 + { 5233 + return __size_+2; 5234 + } 5235 + virtual char* first_demangled_name(char* buf) const 5236 + { 5237 + strncpy(buf, __name_, __size_); 5238 + buf += __size_; 5239 + *buf++ = 'u'; 5240 + *buf++ = 'l'; 5241 + return buf; 5242 + } 5243 + }; 5244 + 5245 + class __long_long 5246 + : public __node 5247 + { 5248 + static const size_t n = sizeof("long long") - 1; 5249 + public: 5250 + 5251 + virtual size_t first_size() const {return n;} 5252 + virtual char* first_demangled_name(char* buf) const 5253 + { 5254 + strncpy(buf, "long long", n); 5255 + return buf + n; 5256 + } 5257 + }; 5258 + 5259 + class __long_long_literal 5260 + : public __node 5261 + { 5262 + public: 5263 + explicit __long_long_literal(const char* __first, const char* __last) 5264 + { 5265 + __name_ = __first; 5266 + __size_ = static_cast<size_t>(__last - __first); 5267 + } 5268 + 5269 + virtual size_t first_size() const 5270 + { 5271 + return __size_+2; 5272 + } 5273 + virtual char* first_demangled_name(char* buf) const 5274 + { 5275 + if (*__name_ == 'n') 5276 + { 5277 + *buf++ = '-'; 5278 + strncpy(buf, __name_+1, __size_-1); 5279 + buf += __size_ - 1; 5280 + } 5281 + else 5282 + { 5283 + strncpy(buf, __name_, __size_); 5284 + buf += __size_; 5285 + } 5286 + *buf++ = 'l'; 5287 + *buf++ = 'l'; 5288 + return buf; 5289 + } 5290 + }; 5291 + 5292 + class __unsigned_long_long 5293 + : public __node 5294 + { 5295 + static const size_t n = sizeof("unsigned long long") - 1; 5296 + public: 5297 + 5298 + virtual size_t first_size() const {return n;} 5299 + virtual char* first_demangled_name(char* buf) const 5300 + { 5301 + strncpy(buf, "unsigned long long", n); 5302 + return buf + n; 5303 + } 5304 + }; 5305 + 5306 + class __unsigned_long_long_literal 5307 + : public __node 5308 + { 5309 + public: 5310 + explicit __unsigned_long_long_literal(const char* __first, const char* __last) 5311 + { 5312 + __name_ = __first; 5313 + __size_ = static_cast<size_t>(__last - __first); 5314 + } 5315 + 5316 + virtual size_t first_size() const 5317 + { 5318 + return __size_+3; 5319 + } 5320 + virtual char* first_demangled_name(char* buf) const 5321 + { 5322 + strncpy(buf, __name_, __size_); 5323 + buf += __size_; 5324 + *buf++ = 'u'; 5325 + *buf++ = 'l'; 5326 + *buf++ = 'l'; 5327 + return buf; 5328 + } 5329 + }; 5330 + 5331 + class __signed_int128 5332 + : public __node 5333 + { 5334 + static const size_t n = sizeof("__int128") - 1; 5335 + public: 5336 + 5337 + virtual size_t first_size() const {return n;} 5338 + virtual char* first_demangled_name(char* buf) const 5339 + { 5340 + strncpy(buf, "__int128", n); 5341 + return buf + n; 5342 + } 5343 + }; 5344 + 5345 + class __int128_literal 5346 + : public __node 5347 + { 5348 + public: 5349 + explicit __int128_literal(const char* __first, const char* __last) 5350 + { 5351 + __name_ = __first; 5352 + __size_ = static_cast<size_t>(__last - __first); 5353 + } 5354 + 5355 + virtual size_t first_size() const 5356 + { 5357 + return __size_+10; 5358 + } 5359 + virtual char* first_demangled_name(char* buf) const 5360 + { 5361 + strncpy(buf, "(__int128)", 10); 5362 + buf += 10; 5363 + if (*__name_ == 'n') 5364 + { 5365 + *buf++ = '-'; 5366 + strncpy(buf, __name_+1, __size_-1); 5367 + buf += __size_ - 1; 5368 + } 5369 + else 5370 + { 5371 + strncpy(buf, __name_, __size_); 5372 + buf += __size_; 5373 + } 5374 + return buf; 5375 + } 5376 + }; 5377 + 5378 + class __unsigned_int128 5379 + : public __node 5380 + { 5381 + static const size_t n = sizeof("unsigned __int128") - 1; 5382 + public: 5383 + 5384 + virtual size_t first_size() const {return n;} 5385 + virtual char* first_demangled_name(char* buf) const 5386 + { 5387 + strncpy(buf, "unsigned __int128", n); 5388 + return buf + n; 5389 + } 5390 + }; 5391 + 5392 + class __unsigned_int128_literal 5393 + : public __node 5394 + { 5395 + public: 5396 + explicit __unsigned_int128_literal(const char* __first, const char* __last) 5397 + { 5398 + __name_ = __first; 5399 + __size_ = static_cast<size_t>(__last - __first); 5400 + } 5401 + 5402 + virtual size_t first_size() const 5403 + { 5404 + return __size_+19; 5405 + } 5406 + virtual char* first_demangled_name(char* buf) const 5407 + { 5408 + strncpy(buf, "(unsigned __int128)", 19); 5409 + buf += 19; 5410 + strncpy(buf, __name_, __size_); 5411 + return buf + __size_; 5412 + } 5413 + }; 5414 + 5415 + class __float_literal 5416 + : public __node 5417 + { 5418 + public: 5419 + explicit __float_literal(float value) 5420 + { 5421 + __value_ = value; 5422 + } 5423 + 5424 + virtual size_t first_size() const 5425 + { 5426 + if (__cached_size_ == -1) 5427 + { 5428 + char num[20] = {0}; 5429 + float v = static_cast<float>(__value_); 5430 + const_cast<long&>(__cached_size_) = sprintf(num, "%a", v)+1; 5431 + } 5432 + return static_cast<size_t>(__cached_size_); 5433 + } 5434 + virtual char* first_demangled_name(char* buf) const 5435 + { 5436 + char num[20] = {0}; 5437 + float v = static_cast<float>(__value_); 5438 + int n = sprintf(num, "%a", v); 5439 + strncpy(buf, num, static_cast<size_t>(n)); 5440 + buf += n; 5441 + *buf++ = 'f'; 5442 + return buf; 5443 + } 5444 + }; 5445 + 5446 + class __float 5447 + : public __node 5448 + { 5449 + static const size_t n = sizeof("float") - 1; 5450 + public: 5451 + 5452 + virtual size_t first_size() const {return n;} 5453 + virtual char* first_demangled_name(char* buf) const 5454 + { 5455 + strncpy(buf, "float", n); 5456 + return buf + n; 5457 + } 5458 + }; 5459 + 5460 + class __double_literal 5461 + : public __node 5462 + { 5463 + public: 5464 + explicit __double_literal(double value) 5465 + { 5466 + __value_ = value; 5467 + } 5468 + 5469 + virtual size_t first_size() const 5470 + { 5471 + if (__cached_size_ == -1) 5472 + { 5473 + char num[30] = {0}; 5474 + double v = static_cast<double>(__value_); 5475 + const_cast<long&>(__cached_size_) = sprintf(num, "%a", v); 5476 + } 5477 + return static_cast<size_t>(__cached_size_); 5478 + } 5479 + virtual char* first_demangled_name(char* buf) const 5480 + { 5481 + char num[30] = {0}; 5482 + double v = static_cast<double>(__value_); 5483 + int n = sprintf(num, "%a", v); 5484 + strncpy(buf, num, static_cast<size_t>(n)); 5485 + return buf + n; 5486 + } 5487 + }; 5488 + 5489 + class __double 5490 + : public __node 5491 + { 5492 + static const size_t n = sizeof("double") - 1; 5493 + public: 5494 + 5495 + virtual size_t first_size() const {return n;} 5496 + virtual char* first_demangled_name(char* buf) const 5497 + { 5498 + strncpy(buf, "double", n); 5499 + return buf + n; 5500 + } 5501 + }; 5502 + 5503 + class __long_double 5504 + : public __node 5505 + { 5506 + static const size_t n = sizeof("long double") - 1; 5507 + public: 5508 + 5509 + virtual size_t first_size() const {return n;} 5510 + virtual char* first_demangled_name(char* buf) const 5511 + { 5512 + strncpy(buf, "long double", n); 5513 + return buf + n; 5514 + } 5515 + }; 5516 + 5517 + class __float128 5518 + : public __node 5519 + { 5520 + static const size_t n = sizeof("__float128") - 1; 5521 + public: 5522 + 5523 + virtual size_t first_size() const {return n;} 5524 + virtual char* first_demangled_name(char* buf) const 5525 + { 5526 + strncpy(buf, "__float128", n); 5527 + return buf + n; 5528 + } 5529 + }; 5530 + 5531 + class __ellipsis 5532 + : public __node 5533 + { 5534 + static const size_t n = sizeof("...") - 1; 5535 + public: 5536 + 5537 + virtual size_t first_size() const {return n;} 5538 + virtual char* first_demangled_name(char* buf) const 5539 + { 5540 + *buf++ = '.'; 5541 + *buf++ = '.'; 5542 + *buf++ = '.'; 5543 + return buf; 5544 + } 5545 + }; 5546 + 5547 + class __decimal64 5548 + : public __node 5549 + { 5550 + static const size_t n = sizeof("decimal64") - 1; 5551 + public: 5552 + 5553 + virtual size_t first_size() const {return n;} 5554 + virtual char* first_demangled_name(char* buf) const 5555 + { 5556 + strncpy(buf, "decimal64", n); 5557 + return buf + n; 5558 + } 5559 + }; 5560 + 5561 + class __decimal128 5562 + : public __node 5563 + { 5564 + static const size_t n = sizeof("decimal128") - 1; 5565 + public: 5566 + 5567 + virtual size_t first_size() const {return n;} 5568 + virtual char* first_demangled_name(char* buf) const 5569 + { 5570 + strncpy(buf, "decimal128", n); 5571 + return buf + n; 5572 + } 5573 + }; 5574 + 5575 + class __decimal32 5576 + : public __node 5577 + { 5578 + static const size_t n = sizeof("decimal32") - 1; 5579 + public: 5580 + 5581 + virtual size_t first_size() const {return n;} 5582 + virtual char* first_demangled_name(char* buf) const 5583 + { 5584 + strncpy(buf, "decimal32", n); 5585 + return buf + n; 5586 + } 5587 + }; 5588 + 5589 + class __decimal16 5590 + : public __node 5591 + { 5592 + static const size_t n = sizeof("decimal16") - 1; 5593 + public: 5594 + 5595 + virtual size_t first_size() const {return n;} 5596 + virtual char* first_demangled_name(char* buf) const 5597 + { 5598 + strncpy(buf, "decimal16", n); 5599 + return buf + n; 5600 + } 5601 + }; 5602 + 5603 + class __d_char32_t 5604 + : public __node 5605 + { 5606 + static const size_t n = sizeof("char32_t") - 1; 5607 + public: 5608 + 5609 + virtual size_t first_size() const {return n;} 5610 + virtual char* first_demangled_name(char* buf) const 5611 + { 5612 + strncpy(buf, "char32_t", n); 5613 + return buf + n; 5614 + } 5615 + }; 5616 + 5617 + class __d_char16_t 5618 + : public __node 5619 + { 5620 + static const size_t n = sizeof("char16_t") - 1; 5621 + public: 5622 + 5623 + virtual size_t first_size() const {return n;} 5624 + virtual char* first_demangled_name(char* buf) const 5625 + { 5626 + strncpy(buf, "char16_t", n); 5627 + return buf + n; 5628 + } 5629 + }; 5630 + 5631 + class __auto 5632 + : public __node 5633 + { 5634 + static const size_t n = sizeof("auto") - 1; 5635 + public: 5636 + 5637 + virtual size_t first_size() const {return n;} 5638 + virtual char* first_demangled_name(char* buf) const 5639 + { 5640 + strncpy(buf, "auto", n); 5641 + return buf + n; 5642 + } 5643 + }; 5644 + 5645 + class __nullptr_t 5646 + : public __node 5647 + { 5648 + static const size_t n = sizeof("std::nullptr_t") - 1; 5649 + public: 5650 + 5651 + virtual size_t first_size() const {return n;} 5652 + virtual char* first_demangled_name(char* buf) const 5653 + { 5654 + strncpy(buf, "std::nullptr_t", n); 5655 + return buf + n; 5656 + } 5657 + }; 5658 + 5659 + class __array 5660 + : public __node 5661 + { 5662 + public: 5663 + 5664 + explicit __array(__node* type) 5665 + { 5666 + __left_ = type; 5667 + } 5668 + 5669 + __array(__node* type, size_t dim) 5670 + { 5671 + __left_ = type; 5672 + __size_ = dim; 5673 + } 5674 + 5675 + __array(__node* type, __node* dim) 5676 + { 5677 + __left_ = type; 5678 + __right_ = dim; 5679 + } 5680 + 5681 + virtual size_t size() const 5682 + { 5683 + if (__cached_size_ == -1) 5684 + { 5685 + size_t r = __left_->size() + 3; 5686 + if (__right_ != 0) 5687 + r += __right_->size(); 5688 + else if (__size_ != 0) 5689 + r += static_cast<size_t>(snprintf(0, 0, "%ld", __size_)); 5690 + const_cast<long&>(__cached_size_) = static_cast<long>(r); 5691 + } 5692 + return static_cast<size_t>(__cached_size_); 5693 + } 5694 + 5695 + virtual char* get_demangled_name(char* buf) const 5696 + { 5697 + buf = __left_->get_demangled_name(buf); 5698 + *buf++ = ' '; 5699 + *buf++ = '['; 5700 + if (__right_ != 0) 5701 + buf = __right_->get_demangled_name(buf); 5702 + else if (__size_ != 0) 5703 + { 5704 + int rs = sprintf(buf, "%ld", __size_); 5705 + buf += rs; 5706 + } 5707 + *buf++ = ']'; 5708 + return buf; 5709 + } 5710 + 5711 + virtual size_t first_size() const 5712 + { 5713 + return __left_->first_size(); 5714 + } 5715 + 5716 + virtual char* first_demangled_name(char* buf) const 5717 + { 5718 + return __left_->first_demangled_name(buf); 5719 + } 5720 + 5721 + virtual size_t second_size() const 5722 + { 5723 + size_t r = 2 + __left_->second_size(); 5724 + if (!__left_->is_array()) 5725 + ++r; 5726 + if (__right_ != 0) 5727 + r += __right_->size(); 5728 + else if (__size_ != 0) 5729 + r += static_cast<size_t>(snprintf(0, 0, "%ld", __size_)); 5730 + return r; 5731 + } 5732 + 5733 + virtual char* second_demangled_name(char* buf) const 5734 + { 5735 + *buf++ = ' '; 5736 + *buf++ = '['; 5737 + if (__right_ != 0) 5738 + buf = __right_->get_demangled_name(buf); 5739 + else if (__size_ != 0) 5740 + { 5741 + int off = sprintf(buf, "%ld", __size_); 5742 + buf += off; 5743 + } 5744 + char* t = buf; 5745 + buf = __left_->second_demangled_name(buf); 5746 + *t = ']'; 5747 + if (buf == t) 5748 + ++buf; 5749 + return buf; 5750 + } 5751 + virtual bool is_array() const 5752 + { 5753 + return true; 5754 + } 5755 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 5756 + { 5757 + bool r = __left_->fix_forward_references(t_begin, t_end); 5758 + if (__right_) 5759 + r = r && __right_->fix_forward_references(t_begin, t_end); 5760 + return r; 5761 + } 5762 + }; 5763 + 5764 + class __pointer_to_member_type 5765 + : public __node 5766 + { 5767 + public: 5768 + 5769 + __pointer_to_member_type(__node* class_type, __node* member_type) 5770 + { 5771 + __left_ = class_type; 5772 + __right_ = member_type; 5773 + } 5774 + 5775 + virtual size_t first_size() const 5776 + { 5777 + if (__cached_size_ == -1) 5778 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 3 5779 + + __right_->first_size() 5780 + + __right_->second_size()); 5781 + return static_cast<size_t>(__cached_size_); 5782 + } 5783 + virtual char* first_demangled_name(char* buf) const 5784 + { 5785 + buf = __right_->first_demangled_name(buf); 5786 + buf = __left_->get_demangled_name(buf); 5787 + *buf++ = ':'; 5788 + *buf++ = ':'; 5789 + *buf++ = '*'; 5790 + return __right_->second_demangled_name(buf); 5791 + } 5792 + virtual __node* base_name() const 5793 + { 5794 + return __left_->base_name(); 5795 + } 5796 + virtual bool is_reference_or_pointer_to_function_or_array() const 5797 + { 5798 + return __right_->is_function(); 5799 + } 5800 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 5801 + { 5802 + return __left_->fix_forward_references(t_begin, t_end) && 5803 + __right_->fix_forward_references(t_begin, t_end); 5804 + } 5805 + }; 5806 + 5807 + class __decltype_node 5808 + : public __node 5809 + { 5810 + public: 5811 + 5812 + explicit __decltype_node(__node* expr) 5813 + { 5814 + __right_ = expr; 5815 + } 5816 + 5817 + virtual size_t first_size() const 5818 + { 5819 + if (__cached_size_ == -1) 5820 + const_cast<long&>(__cached_size_) = static_cast<long>(10 + __right_->size()); 5821 + return static_cast<size_t>(__cached_size_); 5822 + } 5823 + 5824 + virtual char* first_demangled_name(char* buf) const 5825 + { 5826 + strncpy(buf, "decltype(", 9); 5827 + buf += 9; 5828 + buf = __right_->get_demangled_name(buf); 5829 + *buf++ = ')'; 5830 + return buf; 5831 + } 5832 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 5833 + { 5834 + return __right_->fix_forward_references(t_begin, t_end); 5835 + } 5836 + }; 5837 + 5838 + class __nested_delimeter 5839 + : public __node 5840 + { 5841 + public: 5842 + 5843 + explicit __nested_delimeter(__node* prev, __node* arg) 5844 + { 5845 + __left_ = prev; 5846 + __right_ = arg; 5847 + } 5848 + 5849 + virtual size_t first_size() const 5850 + { 5851 + if (__cached_size_ == -1) 5852 + const_cast<long&>(__cached_size_) = static_cast<long>(__left_->size() + 5853 + __right_->size() + 2); 5854 + return static_cast<size_t>(__cached_size_); 5855 + } 5856 + 5857 + virtual char* first_demangled_name(char* buf) const 5858 + { 5859 + buf = __left_->get_demangled_name(buf); 5860 + *buf++ = ':'; 5861 + *buf++ = ':'; 5862 + return __right_->get_demangled_name(buf); 5863 + } 5864 + 5865 + virtual bool ends_with_template(bool parsing = false) const 5866 + { 5867 + return __right_->ends_with_template(parsing); 5868 + } 5869 + virtual __node* base_name() const 5870 + { 5871 + return __right_->base_name(); 5872 + } 5873 + virtual bool is_ctor_dtor_conv() const 5874 + { 5875 + return __right_->is_ctor_dtor_conv(); 5876 + } 5877 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 5878 + { 5879 + return __left_->fix_forward_references(t_begin, t_end) && 5880 + __right_->fix_forward_references(t_begin, t_end); 5881 + } 5882 + virtual __node* extract_cv(__node*&) const 5883 + { 5884 + return __right_->extract_cv(const_cast<__node*&>(__right_)); 5885 + } 5886 + }; 5887 + 5888 + class __unresolved_name 5889 + : public __node 5890 + { 5891 + public: 5892 + 5893 + __unresolved_name(__node* prev, __node* arg) 5894 + { 5895 + __left_ = prev; 5896 + __right_ = arg; 5897 + } 5898 + 5899 + __unresolved_name(bool global, __node* prev, __node* arg) 5900 + { 5901 + __size_ = global; 5902 + __left_ = prev; 5903 + __right_ = arg; 5904 + } 5905 + 5906 + virtual size_t first_size() const 5907 + { 5908 + if (__cached_size_ == -1) 5909 + const_cast<long&>(__cached_size_) = static_cast<long>((__left_ ? 5910 + __left_->size() + 2 : 0) + 5911 + __right_->size() + __size_ * 2); 5912 + return static_cast<size_t>(__cached_size_); 5913 + } 5914 + 5915 + virtual char* first_demangled_name(char* buf) const 5916 + { 5917 + if (__size_) 5918 + { 5919 + *buf++ = ':'; 5920 + *buf++ = ':'; 5921 + } 5922 + if (__left_) 5923 + { 5924 + buf = __left_->get_demangled_name(buf); 5925 + *buf++ = ':'; 5926 + *buf++ = ':'; 5927 + } 5928 + return __right_->get_demangled_name(buf); 5929 + } 5930 + 5931 + virtual bool ends_with_template(bool parsing = false) const 5932 + { 5933 + return __right_->ends_with_template(parsing); 5934 + } 5935 + virtual __node* base_name() const 5936 + { 5937 + return __right_->base_name(); 5938 + } 5939 + virtual bool is_ctor_dtor_conv() const 5940 + { 5941 + return __right_->is_ctor_dtor_conv(); 5942 + } 5943 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 5944 + { 5945 + bool r = true; 5946 + if (__left_) 5947 + r = __left_->fix_forward_references(t_begin, t_end); 5948 + return r && __right_->fix_forward_references(t_begin, t_end); 5949 + } 5950 + virtual __node* extract_cv(__node*&) const 5951 + { 5952 + return __right_->extract_cv(const_cast<__node*&>(__right_)); 5953 + } 5954 + }; 5955 + 5956 + class __string_literal 5957 + : public __node 5958 + { 5959 + public: 5960 + 5961 + virtual size_t first_size() const 5962 + { 5963 + return 14; 5964 + } 5965 + 5966 + virtual char* first_demangled_name(char* buf) const 5967 + { 5968 + strncpy(buf, "string literal", 14); 5969 + return buf + 14; 5970 + } 5971 + }; 5972 + 5973 + class __constructor 5974 + : public __node 5975 + { 5976 + public: 5977 + 5978 + explicit __constructor(__node* name) 5979 + { 5980 + __right_ = name; 5981 + } 5982 + 5983 + virtual size_t first_size() const 5984 + { 5985 + if (__cached_size_ == -1) 5986 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->base_size()); 5987 + return static_cast<size_t>(__cached_size_); 5988 + } 5989 + 5990 + virtual char* first_demangled_name(char* buf) const 5991 + { 5992 + return __right_->get_base_name(buf); 5993 + } 5994 + virtual __node* base_name() const 5995 + { 5996 + return __right_->base_name(); 5997 + } 5998 + virtual bool ends_with_template(bool parsing = false) const 5999 + { 6000 + return __right_->ends_with_template(parsing); 6001 + } 6002 + virtual bool is_ctor_dtor_conv() const 6003 + { 6004 + return true; 6005 + } 6006 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 6007 + { 6008 + return __right_->fix_forward_references(t_begin, t_end); 6009 + } 6010 + }; 6011 + 6012 + class __destructor 6013 + : public __node 6014 + { 6015 + public: 6016 + 6017 + explicit __destructor(__node* name) 6018 + { 6019 + __right_ = name; 6020 + } 6021 + 6022 + virtual size_t first_size() const 6023 + { 6024 + if (__cached_size_ == -1) 6025 + const_cast<long&>(__cached_size_) = static_cast<long>(__right_->base_size() + 1); 6026 + return static_cast<size_t>(__cached_size_); 6027 + } 6028 + 6029 + virtual char* first_demangled_name(char* buf) const 6030 + { 6031 + *buf++ = '~'; 6032 + return __right_->get_base_name(buf); 6033 + } 6034 + virtual __node* base_name() const 6035 + { 6036 + return __right_->base_name(); 6037 + } 6038 + virtual bool is_ctor_dtor_conv() const 6039 + { 6040 + return true; 6041 + } 6042 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 6043 + { 6044 + return __right_->fix_forward_references(t_begin, t_end); 6045 + } 6046 + }; 6047 + 6048 + class __dot_suffix 6049 + : public __node 6050 + { 6051 + public: 6052 + __dot_suffix(__node* name, const char* suffix, size_t sz) 6053 + { 6054 + __left_ = name; 6055 + __name_ = suffix; 6056 + __size_ = sz; 6057 + } 6058 + 6059 + virtual size_t first_size() const 6060 + { 6061 + if (__cached_size_ == -1) 6062 + { 6063 + size_t off = __left_->size(); 6064 + off += __size_ + 3; 6065 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 6066 + } 6067 + return static_cast<size_t>(__cached_size_); 6068 + } 6069 + virtual char* first_demangled_name(char* buf) const 6070 + { 6071 + buf = __left_->get_demangled_name(buf); 6072 + *buf++ = ' '; 6073 + *buf++ = '('; 6074 + strncpy(buf, __name_, __size_); 6075 + buf += __size_; 6076 + *buf++ = ')'; 6077 + return buf; 6078 + } 6079 + virtual __node* base_name() const 6080 + { 6081 + return __left_->base_name(); 6082 + } 6083 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 6084 + { 6085 + return __left_->fix_forward_references(t_begin, t_end); 6086 + } 6087 + }; 6088 + 6089 + class __vector_type 6090 + : public __node 6091 + { 6092 + public: 6093 + __vector_type(__node* type, const char* num, size_t sz) 6094 + { 6095 + __left_ = type; 6096 + __name_ = num; 6097 + __size_ = sz; 6098 + } 6099 + 6100 + __vector_type(__node* type, __node* num) 6101 + { 6102 + __left_ = type; 6103 + __right_ = num; 6104 + } 6105 + 6106 + virtual size_t first_size() const 6107 + { 6108 + if (__cached_size_ == -1) 6109 + { 6110 + size_t off = 5; 6111 + if (__left_) 6112 + off = __left_->size(); 6113 + off += 9; 6114 + if (__right_) 6115 + off += __right_->size(); 6116 + else if (__size_ > 0) 6117 + off += __size_; 6118 + const_cast<long&>(__cached_size_) = static_cast<long>(off); 6119 + } 6120 + return static_cast<size_t>(__cached_size_); 6121 + } 6122 + virtual char* first_demangled_name(char* buf) const 6123 + { 6124 + if (__left_) 6125 + buf = __left_->get_demangled_name(buf); 6126 + else 6127 + { 6128 + strncpy(buf, "pixel", 5); 6129 + buf += 5; 6130 + } 6131 + strncpy(buf, " vector[", 8); 6132 + buf += 8; 6133 + if (__right_) 6134 + buf = __right_->get_demangled_name(buf); 6135 + else if (__size_ > 0) 6136 + { 6137 + strncpy(buf, __name_, __size_); 6138 + buf += __size_; 6139 + } 6140 + *buf++ = ']'; 6141 + return buf; 6142 + } 6143 + virtual __node* base_name() const 6144 + { 6145 + if (__left_) 6146 + return __left_->base_name(); 6147 + return __left_; 6148 + } 6149 + virtual bool fix_forward_references(__node** t_begin, __node** t_end) 6150 + { 6151 + bool r = true; 6152 + if (__left_) 6153 + r = __left_->fix_forward_references(t_begin, t_end); 6154 + if (__right_) 6155 + r = r && __right_->fix_forward_references(t_begin, t_end); 6156 + return r; 6157 + } 6158 + }; 6159 + 6160 + 6161 + enum {invalid_args = -3, invalid_mangled_name, memory_alloc_failure, success, 6162 + not_yet_implemented}; 6163 + 6164 + __demangle_tree::__demangle_tree(const char* mangled_name, char* buf, size_t bs) 6165 + : __mangled_name_begin_(0), __mangled_name_end_(0), 6166 + __status_(invalid_mangled_name), __root_(0), 6167 + __node_begin_(0), __node_end_(0), __node_cap_(0), 6168 + __sub_begin_(0), __sub_end_(0), __sub_cap_(0), 6169 + __t_begin_(0), __t_end_(0), __t_cap_(0), 6170 + __tag_templates_(true), 6171 + __fix_forward_references_(false) 6172 + { 6173 + size_t n = strlen(mangled_name); 6174 + size_t ms = n + 2*n*sizeof(__node) + 2*n*sizeof(__node*); 6175 + char* m; 6176 + if (ms <= bs) 6177 + { 6178 + m = buf; 6179 + __owns_buf_ = false; 6180 + } 6181 + else 6182 + { 6183 + m = static_cast<char*>(malloc(ms)); 6184 + __owns_buf_ = true; 6185 + } 6186 + if (m == NULL) 6187 + { 6188 + __status_ = memory_alloc_failure; 6189 + return; 6190 + } 6191 + __node_begin_ = __node_end_ = (__node*)(m); 6192 + __node_cap_ = __node_begin_ + 2*n; 6193 + __sub_begin_ = __sub_end_ = (__node**)(__node_cap_); 6194 + __sub_cap_ = __sub_begin_ + n; 6195 + __t_begin_ = __t_end_ = (__node**)(__sub_cap_); 6196 + __t_cap_ = __t_begin_ + n; 6197 + __mangled_name_begin_ = (const char*)(__t_cap_); 6198 + __mangled_name_end_ = __mangled_name_begin_ + n; 6199 + strncpy(const_cast<char*>(__mangled_name_begin_), mangled_name, n); 6200 + } 6201 + 6202 + __demangle_tree::~__demangle_tree() 6203 + { 6204 + if (__owns_buf_) 6205 + free(__node_begin_); 6206 + } 6207 + 6208 + __demangle_tree::__demangle_tree(__demangle_tree& t) 6209 + : __mangled_name_begin_(t.__mangled_name_begin_), 6210 + __mangled_name_end_(t.__mangled_name_end_), 6211 + __status_(t.__status_), __root_(t.__root_), 6212 + __node_begin_(t.__node_begin_), __node_end_(t.__node_end_), 6213 + __node_cap_(t.__node_cap_), 6214 + __sub_begin_(t.__sub_begin_), __sub_end_(t.__sub_end_), 6215 + __sub_cap_(t.__sub_cap_), 6216 + __t_begin_(t.__t_begin_), __t_end_(t.__t_end_), 6217 + __t_cap_(t.__t_cap_), 6218 + __tag_templates_(t.__tag_templates_), 6219 + __fix_forward_references_(t.__fix_forward_references_), 6220 + __owns_buf_(t.__owns_buf_) 6221 + { 6222 + t.__mangled_name_begin_ = 0; 6223 + t.__mangled_name_end_ = 0; 6224 + t.__status_ = invalid_mangled_name; 6225 + t.__root_ = 0; 6226 + t.__node_begin_ = t.__node_end_ = t.__node_cap_ = 0; 6227 + t.__sub_begin_ = t.__sub_end_ = t.__sub_cap_ = 0; 6228 + t.__t_begin_ = t.__t_end_ = t.__t_cap_ = 0; 6229 + t.__owns_buf_ = false; 6230 + } 6231 + 6232 + __demangle_tree::__demangle_tree(__demangle_tree_rv rv) 6233 + : __mangled_name_begin_(rv.ptr_->__mangled_name_begin_), 6234 + __mangled_name_end_(rv.ptr_->__mangled_name_end_), 6235 + __status_(rv.ptr_->__status_), __root_(rv.ptr_->__root_), 6236 + __node_begin_(rv.ptr_->__node_begin_), __node_end_(rv.ptr_->__node_end_), 6237 + __node_cap_(rv.ptr_->__node_cap_), 6238 + __sub_begin_(rv.ptr_->__sub_begin_), __sub_end_(rv.ptr_->__sub_end_), 6239 + __sub_cap_(rv.ptr_->__sub_cap_), 6240 + __t_begin_(rv.ptr_->__t_begin_), __t_end_(rv.ptr_->__t_end_), 6241 + __t_cap_(rv.ptr_->__t_cap_), 6242 + __tag_templates_(rv.ptr_->__tag_templates_), 6243 + __fix_forward_references_(rv.ptr_->__fix_forward_references_), 6244 + __owns_buf_(rv.ptr_->__owns_buf_) 6245 + { 6246 + rv.ptr_->__mangled_name_begin_ = 0; 6247 + rv.ptr_->__mangled_name_end_ = 0; 6248 + rv.ptr_->__status_ = invalid_mangled_name; 6249 + rv.ptr_->__root_ = 0; 6250 + rv.ptr_->__node_begin_ = rv.ptr_->__node_end_ = rv.ptr_->__node_cap_ = 0; 6251 + rv.ptr_->__sub_begin_ = rv.ptr_->__sub_end_ = rv.ptr_->__sub_cap_ = 0; 6252 + rv.ptr_->__t_begin_ = rv.ptr_->__t_end_ = rv.ptr_->__t_cap_ = 0; 6253 + rv.ptr_->__owns_buf_ = false; 6254 + } 6255 + 6256 + int 6257 + __demangle_tree::__status() const 6258 + { 6259 + return __status_; 6260 + } 6261 + 6262 + size_t 6263 + __demangle_tree::size() const 6264 + { 6265 + return __status_ == success ? __root_->size() : 0; 6266 + } 6267 + 6268 + char* 6269 + __demangle_tree::__get_demangled_name(char* buf) const 6270 + { 6271 + if (__status_ == success) 6272 + return __root_->get_demangled_name(buf); 6273 + return 0; 6274 + } 6275 + 6276 + template <class _Tp> 6277 + bool 6278 + __demangle_tree::__make() 6279 + { 6280 + if (__node_end_ < __node_cap_) 6281 + { 6282 + ::new (__node_end_) _Tp(); 6283 + __root_ = __node_end_; 6284 + ++__node_end_; 6285 + return true; 6286 + } 6287 + __status_ = memory_alloc_failure; 6288 + return false; 6289 + } 6290 + 6291 + template <class _Tp, class _A0> 6292 + bool 6293 + __demangle_tree::__make(_A0 __a0) 6294 + { 6295 + if (__node_end_ < __node_cap_) 6296 + { 6297 + ::new (__node_end_) _Tp(__a0); 6298 + __root_ = __node_end_; 6299 + ++__node_end_; 6300 + return true; 6301 + } 6302 + __status_ = memory_alloc_failure; 6303 + return false; 6304 + } 6305 + 6306 + template <class _Tp, class _A0, class _A1> 6307 + bool 6308 + __demangle_tree::__make(_A0 __a0, _A1 __a1) 6309 + { 6310 + if (__node_end_ < __node_cap_) 6311 + { 6312 + ::new (__node_end_) _Tp(__a0, __a1); 6313 + __root_ = __node_end_; 6314 + ++__node_end_; 6315 + return true; 6316 + } 6317 + __status_ = memory_alloc_failure; 6318 + return false; 6319 + } 6320 + 6321 + template <class _Tp, class _A0, class _A1, class _A2> 6322 + bool 6323 + __demangle_tree::__make(_A0 __a0, _A1 __a1, _A2 __a2) 6324 + { 6325 + if (__node_end_ < __node_cap_) 6326 + { 6327 + ::new (__node_end_) _Tp(__a0, __a1, __a2); 6328 + __root_ = __node_end_; 6329 + ++__node_end_; 6330 + return true; 6331 + } 6332 + __status_ = memory_alloc_failure; 6333 + return false; 6334 + } 6335 + 6336 + template <class _Tp, class _A0, class _A1, class _A2, class _A3> 6337 + bool 6338 + __demangle_tree::__make(_A0 __a0, _A1 __a1, _A2 __a2, _A3 __a3) 6339 + { 6340 + if (__node_end_ < __node_cap_) 6341 + { 6342 + ::new (__node_end_) _Tp(__a0, __a1, __a2, __a3); 6343 + __root_ = __node_end_; 6344 + ++__node_end_; 6345 + return true; 6346 + } 6347 + __status_ = memory_alloc_failure; 6348 + return false; 6349 + } 6350 + 6351 + template <class _Tp, class _A0, class _A1, class _A2, class _A3, class _A4> 6352 + bool 6353 + __demangle_tree::__make(_A0 __a0, _A1 __a1, _A2 __a2, _A3 __a3, _A4 __a4) 6354 + { 6355 + if (__node_end_ < __node_cap_) 6356 + { 6357 + ::new (__node_end_) _Tp(__a0, __a1, __a2, __a3, __a4); 6358 + __root_ = __node_end_; 6359 + ++__node_end_; 6360 + return true; 6361 + } 6362 + __status_ = memory_alloc_failure; 6363 + return false; 6364 + } 6365 + 6366 + template <class _Tp, class _A0, class _A1, class _A2, class _A3, class _A4, 6367 + class _A5> 6368 + bool 6369 + __demangle_tree::__make(_A0 __a0, _A1 __a1, _A2 __a2, _A3 __a3, _A4 __a4, 6370 + _A5 __a5) 6371 + { 6372 + if (__node_end_ < __node_cap_) 6373 + { 6374 + ::new (__node_end_) _Tp(__a0, __a1, __a2, __a3, __a4, __a5); 6375 + __root_ = __node_end_; 6376 + ++__node_end_; 6377 + return true; 6378 + } 6379 + __status_ = memory_alloc_failure; 6380 + return false; 6381 + } 6382 + 6383 + // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const 6384 + // [R | O] # & or && 6385 + 6386 + const char* 6387 + __demangle_tree::__parse_cv_qualifiers(const char* first, const char* last, 6388 + unsigned& cv, bool look_for_ref_quals) 6389 + { 6390 + if (look_for_ref_quals) 6391 + { 6392 + for (; first != last; ++first) 6393 + { 6394 + switch (*first) 6395 + { 6396 + case 'r': 6397 + cv |= 4; 6398 + break; 6399 + case 'V': 6400 + cv |= 2; 6401 + break; 6402 + case 'K': 6403 + cv |= 1; 6404 + break; 6405 + case 'R': 6406 + cv |= 8; 6407 + break; 6408 + case 'O': 6409 + cv |= 16; 6410 + break; 6411 + default: 6412 + return first; 6413 + } 6414 + } 6415 + } 6416 + else 6417 + { 6418 + for (; first != last; ++first) 6419 + { 6420 + switch (*first) 6421 + { 6422 + case 'r': 6423 + cv |= 4; 6424 + break; 6425 + case 'V': 6426 + cv |= 2; 6427 + break; 6428 + case 'K': 6429 + cv |= 1; 6430 + break; 6431 + default: 6432 + return first; 6433 + } 6434 + } 6435 + } 6436 + return first; 6437 + } 6438 + 6439 + // <builtin-type> ::= v # void 6440 + // ::= w # wchar_t 6441 + // ::= b # bool 6442 + // ::= c # char 6443 + // ::= a # signed char 6444 + // ::= h # unsigned char 6445 + // ::= s # short 6446 + // ::= t # unsigned short 6447 + // ::= i # int 6448 + // ::= j # unsigned int 6449 + // ::= l # long 6450 + // ::= m # unsigned long 6451 + // ::= x # long long, __int64 6452 + // ::= y # unsigned long long, __int64 6453 + // ::= n # __int128 6454 + // ::= o # unsigned __int128 6455 + // ::= f # float 6456 + // ::= d # double 6457 + // ::= e # long double, __float80 6458 + // ::= g # __float128 6459 + // ::= z # ellipsis 6460 + // ::= Dd # IEEE 754r decimal floating point (64 bits) 6461 + // ::= De # IEEE 754r decimal floating point (128 bits) 6462 + // ::= Df # IEEE 754r decimal floating point (32 bits) 6463 + // ::= Dh # IEEE 754r half-precision floating point (16 bits) 6464 + // ::= Di # char32_t 6465 + // ::= Ds # char16_t 6466 + // ::= Da # auto (in dependent new-expressions) 6467 + // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) 6468 + // ::= u <source-name> # vendor extended type 6469 + 6470 + const char* 6471 + __demangle_tree::__parse_builtin_type(const char* first, const char* last) 6472 + { 6473 + if (first != last) 6474 + { 6475 + switch (*first) 6476 + { 6477 + case 'v': 6478 + if (__make<__void>()) 6479 + ++first; 6480 + break; 6481 + case 'w': 6482 + if (__make<__wchar_t>()) 6483 + ++first; 6484 + break; 6485 + case 'b': 6486 + if (__make<__bool>()) 6487 + ++first; 6488 + break; 6489 + case 'c': 6490 + if (__make<__char>()) 6491 + ++first; 6492 + break; 6493 + case 'a': 6494 + if (__make<__signed_char>()) 6495 + ++first; 6496 + break; 6497 + case 'h': 6498 + if (__make<__unsigned_char>()) 6499 + ++first; 6500 + break; 6501 + case 's': 6502 + if (__make<__short>()) 6503 + ++first; 6504 + break; 6505 + case 't': 6506 + if (__make<__unsigned_short>()) 6507 + ++first; 6508 + break; 6509 + case 'i': 6510 + if (__make<__int>()) 6511 + ++first; 6512 + break; 6513 + case 'j': 6514 + if (__make<__unsigned_int>()) 6515 + ++first; 6516 + break; 6517 + case 'l': 6518 + if (__make<__long>()) 6519 + ++first; 6520 + break; 6521 + case 'm': 6522 + if (__make<__unsigned_long>()) 6523 + ++first; 6524 + break; 6525 + case 'x': 6526 + if (__make<__long_long>()) 6527 + ++first; 6528 + break; 6529 + case 'y': 6530 + if (__make<__unsigned_long_long>()) 6531 + ++first; 6532 + break; 6533 + case 'n': 6534 + if (__make<__signed_int128>()) 6535 + ++first; 6536 + break; 6537 + case 'o': 6538 + if (__make<__unsigned_int128>()) 6539 + ++first; 6540 + break; 6541 + case 'f': 6542 + if (__make<__float>()) 6543 + ++first; 6544 + break; 6545 + case 'd': 6546 + if (__make<__double>()) 6547 + ++first; 6548 + break; 6549 + case 'e': 6550 + if (__make<__long_double>()) 6551 + ++first; 6552 + break; 6553 + case 'g': 6554 + if (__make<__float128>()) 6555 + ++first; 6556 + break; 6557 + case 'z': 6558 + if (__make<__ellipsis>()) 6559 + ++first; 6560 + break; 6561 + case 'D': 6562 + if (first+1 != last) 6563 + { 6564 + switch (first[1]) 6565 + { 6566 + case 'd': 6567 + if (__make<__decimal64>()) 6568 + first += 2; 6569 + break; 6570 + case 'e': 6571 + if (__make<__decimal128>()) 6572 + first += 2; 6573 + break; 6574 + case 'f': 6575 + if (__make<__decimal32>()) 6576 + first += 2; 6577 + break; 6578 + case 'h': 6579 + if (__make<__decimal16>()) 6580 + first += 2; 6581 + break; 6582 + case 'i': 6583 + if (__make<__d_char32_t>()) 6584 + first += 2; 6585 + break; 6586 + case 's': 6587 + if (__make<__d_char16_t>()) 6588 + first += 2; 6589 + break; 6590 + case 'a': 6591 + if (__make<__auto>()) 6592 + first += 2; 6593 + break; 6594 + case 'n': 6595 + if (__make<__nullptr_t>()) 6596 + first += 2; 6597 + break; 6598 + } 6599 + } 6600 + break; 6601 + } 6602 + } 6603 + return first; 6604 + } 6605 + 6606 + // <bare-function-type> ::= <signature type>+ 6607 + // # types are possible return type, then parameter types 6608 + 6609 + const char* 6610 + __demangle_tree::__parse_bare_function_type(const char* first, const char* last) 6611 + { 6612 + if (first != last) 6613 + { 6614 + bool prev_tag_templates = __tag_templates_; 6615 + __tag_templates_ = false; 6616 + const char* t = __parse_type(first, last); 6617 + if (t != first && __make<__list>(__root_)) 6618 + { 6619 + const char* t0 = t; 6620 + __node* head = __root_; 6621 + __node* prev = head; 6622 + while (true) 6623 + { 6624 + t = __parse_type(t0, last); 6625 + if (t != t0) 6626 + { 6627 + if (__make<__list>(__root_)) 6628 + { 6629 + t0 = t; 6630 + prev->__right_ = __root_; 6631 + __root_->__size_ = prev->__size_ + 1; 6632 + prev = __root_; 6633 + } 6634 + else 6635 + break; 6636 + } 6637 + else 6638 + { 6639 + first = t; 6640 + __root_ = head; 6641 + break; 6642 + } 6643 + } 6644 + } 6645 + __tag_templates_ = prev_tag_templates; 6646 + } 6647 + return first; 6648 + } 6649 + 6650 + // <function-type> ::= F [Y] <bare-function-type> E 6651 + 6652 + const char* 6653 + __demangle_tree::__parse_function_type(const char* first, const char* last) 6654 + { 6655 + if (first != last && *first == 'F') 6656 + { 6657 + const char* t = first+1; 6658 + if (t != last) 6659 + { 6660 + bool externC = false; 6661 + if (*t == 'Y') 6662 + { 6663 + externC = true; 6664 + if (++t == last) 6665 + return first; 6666 + } 6667 + const char* t1 = __parse_type(t, last); 6668 + if (t1 != t) 6669 + { 6670 + __node* ret = __root_; 6671 + t = t1; 6672 + t1 = __parse_bare_function_type(t, last); 6673 + if (t1 != t && t1 != last && *t1 == 'E') 6674 + { 6675 + if (dynamic_cast<__void*>(__root_->__left_) != NULL) 6676 + __root_->__left_ = NULL; 6677 + if (__make<__function_signature>(ret, __root_)) 6678 + { 6679 + if (__make<__function>((__node*)0, __root_)) 6680 + first = t1+1; 6681 + } 6682 + } 6683 + } 6684 + } 6685 + } 6686 + return first; 6687 + } 6688 + 6689 + const char* 6690 + __demangle_tree::__parse_hex_number(const char* first, const char* last, unsigned long long& n) 6691 + { 6692 + const char* t = first; 6693 + for (; t != last && isxdigit(*t); ++t) 6694 + { 6695 + if (t == first) 6696 + n = 0; 6697 + if (isdigit(*t)) 6698 + n = n * 16 + static_cast<unsigned long long>(*t - '0'); 6699 + else if (isupper(*t)) 6700 + n = n * 16 + static_cast<unsigned long long>(*t - 'A') + 10; 6701 + else 6702 + n = n * 16 + static_cast<unsigned long long>(*t - 'a') + 10; 6703 + } 6704 + first = t; 6705 + return first; 6706 + } 6707 + 6708 + // <expr-primary> ::= L <type> <value number> E # integer literal 6709 + // ::= L <type> <value float> E # floating literal 6710 + // ::= L <string type> E # string literal 6711 + // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE") 6712 + // ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) 6713 + // ::= L <mangled-name> E # external name 6714 + 6715 + const char* 6716 + __demangle_tree::__parse_expr_primary(const char* first, const char* last) 6717 + { 6718 + if (last - first >= 4 && *first == 'L') 6719 + { 6720 + switch (first[1]) 6721 + { 6722 + case 'w': 6723 + { 6724 + const char* t = __parse_number(first+2, last); 6725 + if (t != first+2 && t != last && *t == 'E') 6726 + { 6727 + if (__make<__wchar_t_literal>(first+2, t)) 6728 + first = t+1; 6729 + } 6730 + } 6731 + break; 6732 + case 'b': 6733 + if (first[3] == 'E') 6734 + { 6735 + switch (first[2]) 6736 + { 6737 + case '0': 6738 + if (__make<__bool_literal>("false", 5u)) 6739 + first += 4; 6740 + break; 6741 + case '1': 6742 + if (__make<__bool_literal>("true", 4u)) 6743 + first += 4; 6744 + break; 6745 + } 6746 + } 6747 + break; 6748 + case 'c': 6749 + { 6750 + const char* t = __parse_number(first+2, last); 6751 + if (t != first+2 && t != last && *t == 'E') 6752 + { 6753 + if (__make<__char_literal>(first+2, t)) 6754 + first = t+1; 6755 + } 6756 + } 6757 + break; 6758 + case 'a': 6759 + { 6760 + const char* t = __parse_number(first+2, last); 6761 + if (t != first+2 && t != last && *t == 'E') 6762 + { 6763 + if (__make<__signed_char_literal>(first+2, t)) 6764 + first = t+1; 6765 + } 6766 + } 6767 + break; 6768 + case 'h': 6769 + { 6770 + const char* t = __parse_number(first+2, last); 6771 + if (t != first+2 && t != last && *t == 'E') 6772 + { 6773 + if (__make<__unsigned_char_literal>(first+2, t)) 6774 + first = t+1; 6775 + } 6776 + } 6777 + break; 6778 + case 's': 6779 + { 6780 + const char* t = __parse_number(first+2, last); 6781 + if (t != first+2 && t != last && *t == 'E') 6782 + { 6783 + if (__make<__short_literal>(first+2, t)) 6784 + first = t+1; 6785 + } 6786 + } 6787 + break; 6788 + case 't': 6789 + { 6790 + const char* t = __parse_number(first+2, last); 6791 + if (t != first+2 && t != last && *t == 'E') 6792 + { 6793 + if (__make<__unsigned_short_literal>(first+2, t)) 6794 + first = t+1; 6795 + } 6796 + } 6797 + break; 6798 + case 'i': 6799 + { 6800 + const char* t = __parse_number(first+2, last); 6801 + if (t != first+2 && t != last && *t == 'E') 6802 + { 6803 + if (__make<__int_literal>(first+2, t)) 6804 + first = t+1; 6805 + } 6806 + } 6807 + break; 6808 + case 'j': 6809 + { 6810 + const char* t = __parse_number(first+2, last); 6811 + if (t != first+2 && t != last && *t == 'E') 6812 + { 6813 + if (__make<__unsigned_int_literal>(first+2, t)) 6814 + first = t+1; 6815 + } 6816 + } 6817 + break; 6818 + case 'l': 6819 + { 6820 + const char* t = __parse_number(first+2, last); 6821 + if (t != first+2 && t != last && *t == 'E') 6822 + { 6823 + if (__make<__long_literal>(first+2, t)) 6824 + first = t+1; 6825 + } 6826 + } 6827 + break; 6828 + case 'm': 6829 + { 6830 + const char* t = __parse_number(first+2, last); 6831 + if (t != first+2 && t != last && *t == 'E') 6832 + { 6833 + if (__make<__unsigned_long_literal>(first+2, t)) 6834 + first = t+1; 6835 + } 6836 + } 6837 + break; 6838 + case 'x': 6839 + { 6840 + const char* t = __parse_number(first+2, last); 6841 + if (t != first+2 && t != last && *t == 'E') 6842 + { 6843 + if (__make<__long_long_literal>(first+2, t)) 6844 + first = t+1; 6845 + } 6846 + } 6847 + break; 6848 + case 'y': 6849 + { 6850 + const char* t = __parse_number(first+2, last); 6851 + if (t != first+2 && t != last && *t == 'E') 6852 + { 6853 + if (__make<__unsigned_long_long_literal>(first+2, t)) 6854 + first = t+1; 6855 + } 6856 + } 6857 + break; 6858 + case 'n': 6859 + { 6860 + const char* t = __parse_number(first+2, last); 6861 + if (t != first+2 && t != last && *t == 'E') 6862 + { 6863 + if (__make<__int128_literal>(first+2, t)) 6864 + first = t+1; 6865 + } 6866 + } 6867 + break; 6868 + case 'o': 6869 + { 6870 + const char* t = __parse_number(first+2, last); 6871 + if (t != first+2 && t != last && *t == 'E') 6872 + { 6873 + if (__make<__unsigned_int128_literal>(first+2, t)) 6874 + first = t+1; 6875 + } 6876 + } 6877 + break; 6878 + case 'f': 6879 + { 6880 + if (last - (first+2) <= 8) 6881 + return first; 6882 + unsigned long long j; 6883 + const char* t = __parse_hex_number(first+2, first+10, j); 6884 + if (t != first+2 && t != last && *t == 'E') 6885 + { 6886 + unsigned i = static_cast<unsigned>(j); 6887 + float value = *(float*)&i; 6888 + if (__make<__float_literal>(value)) 6889 + first = t+1; 6890 + } 6891 + } 6892 + break; 6893 + case 'd': 6894 + { 6895 + if (last - (first+2) <= 16) 6896 + return first; 6897 + unsigned long long j; 6898 + const char* t = __parse_hex_number(first+2, first+18, j); 6899 + if (t != first+2 && t != last && *t == 'E') 6900 + { 6901 + double value = *(double*)&j; 6902 + if (__make<__double_literal>(value)) 6903 + first = t+1; 6904 + } 6905 + } 6906 + break; 6907 + case 'e': 6908 + break; 6909 + case '_': 6910 + if (first[2] == 'Z') 6911 + { 6912 + const char* t = __parse_encoding(first+3, last); 6913 + if (t != first+3 && t != last && *t == 'E') 6914 + first = t+1; 6915 + } 6916 + break; 6917 + default: 6918 + { 6919 + // might be named type 6920 + const char* t = __parse_type(first+1, last); 6921 + if (t != first+1 && t != last) 6922 + { 6923 + if (*t != 'E') 6924 + { 6925 + const char* n = t; 6926 + for (; n != last && isdigit(*n); ++n) 6927 + ; 6928 + if (n != t && n != last && *n == 'E') 6929 + { 6930 + if (__make<__cast_literal>(__root_, t, n)) 6931 + { 6932 + first = n+1; 6933 + break; 6934 + } 6935 + } 6936 + } 6937 + else 6938 + { 6939 + first = t+1; 6940 + break; 6941 + } 6942 + } 6943 + } 6944 + // assert(!"case in __parse_expr_primary not implemented"); 6945 + __status_ = not_yet_implemented; 6946 + } 6947 + } 6948 + return first; 6949 + } 6950 + 6951 + // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ 6952 + // ::= <closure-type-name> 6953 + // 6954 + // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ 6955 + // 6956 + // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters 6957 + 6958 + const char* 6959 + __demangle_tree::__parse_unnamed_type_name(const char* first, const char* last) 6960 + { 6961 + if (last - first > 2 && first[0] == 'U') 6962 + { 6963 + char type = first[1]; 6964 + switch (type) 6965 + { 6966 + case 't': 6967 + case 'l': 6968 + first += 2; 6969 + 6970 + if (type == 'l') 6971 + { 6972 + __root_ = 0; 6973 + if (first[0] == 'v') 6974 + { 6975 + // void lambda 6976 + ++first; 6977 + if (first[0] == 'E') 6978 + ++first; 6979 + else 6980 + return first; 6981 + } 6982 + else 6983 + { 6984 + while (first[0] && first[0] != 'E') 6985 + { 6986 + const char *old = first; 6987 + first = __parse_type(first, last); 6988 + if (first == old) 6989 + break; 6990 + } 6991 + if (first[0] == 'E') 6992 + ++first; 6993 + else 6994 + return first; 6995 + } 6996 + } 6997 + const char *number_start = first; 6998 + first = __parse_number(first, last); 6999 + const char *number_end = first; 7000 + if (first[0] == '_') 7001 + { 7002 + ++first; 7003 + } 7004 + else 7005 + return first; 7006 + 7007 + if (type == 'l') 7008 + __make<__lambda>(__root_, number_start, static_cast<size_t>(number_end - number_start)); 7009 + else 7010 + __make<__unnamed>(number_start, static_cast<size_t>(number_end - number_start)); 7011 + 7012 + break; 7013 + } 7014 + } 7015 + return first; 7016 + } 7017 + 7018 + // <ctor-dtor-name> ::= C1 # complete object constructor 7019 + // ::= C2 # base object constructor 7020 + // ::= C3 # complete object allocating constructor 7021 + // ::= D0 # deleting destructor 7022 + // ::= D1 # complete object destructor 7023 + // ::= D2 # base object destructor 7024 + 7025 + const char* 7026 + __demangle_tree::__parse_ctor_dtor_name(const char* first, const char* last) 7027 + { 7028 + if (last-first >= 2 && __root_) 7029 + { 7030 + switch (first[0]) 7031 + { 7032 + case 'C': 7033 + switch (first[1]) 7034 + { 7035 + case '1': 7036 + case '2': 7037 + case '3': 7038 + if (__make<__constructor>(__root_->base_name())) 7039 + first += 2; 7040 + break; 7041 + } 7042 + break; 7043 + case 'D': 7044 + switch (first[1]) 7045 + { 7046 + case '0': 7047 + case '1': 7048 + case '2': 7049 + if (__make<__destructor>(__root_->base_name())) 7050 + first += 2; 7051 + break; 7052 + } 7053 + break; 7054 + } 7055 + } 7056 + return first; 7057 + } 7058 + 7059 + const char* 7060 + __demangle_tree::__parse_unscoped_template_name(const char* first, const char*) 7061 + { 7062 + // assert(!"__parse_unscoped_template_name not implemented"); 7063 + __status_ = not_yet_implemented; 7064 + return first; 7065 + } 7066 + 7067 + // <discriminator> := _ <non-negative number> # when number < 10 7068 + // := __ <non-negative number> _ # when number >= 10 7069 + // extension := decimal-digit+ 7070 + 7071 + const char* 7072 + __demangle_tree::__parse_discriminator(const char* first, const char* last) 7073 + { 7074 + // parse but ignore discriminator 7075 + if (first != last) 7076 + { 7077 + if (*first == '_') 7078 + { 7079 + const char* t1 = first+1; 7080 + if (t1 != last) 7081 + { 7082 + if (isdigit(*t1)) 7083 + first = t1+1; 7084 + else if (*t1 == '_') 7085 + { 7086 + for (++t1; t1 != last && isdigit(*t1); ++t1) 7087 + ; 7088 + if (t1 != last && *t1 == '_') 7089 + first = t1 + 1; 7090 + } 7091 + } 7092 + } 7093 + else if (isdigit(*first)) 7094 + { 7095 + const char* t1 = first+1; 7096 + for (; t1 != last && isdigit(*t1); ++t1) 7097 + ; 7098 + first = t1; 7099 + } 7100 + } 7101 + return first; 7102 + } 7103 + 7104 + // <local-name> := Z <function encoding> E <entity name> [<discriminator>] 7105 + // := Z <function encoding> E s [<discriminator>] 7106 + // := Z <function encoding> Ed [ <parameter number> ] _ <entity name> 7107 + 7108 + const char* 7109 + __demangle_tree::__parse_local_name(const char* first, const char* last) 7110 + { 7111 + if (first != last && *first == 'Z') 7112 + { 7113 + const char* t = __parse_encoding(first+1, last); 7114 + if (t != first+1 && t != last && *t == 'E' && ++t != last) 7115 + { 7116 + __node* encoding = __root_; 7117 + switch (*t) 7118 + { 7119 + case 's': 7120 + { 7121 + const char*t1 = __parse_discriminator(t+1, last); 7122 + if (__make<__string_literal>()) 7123 + { 7124 + if (__make<__nested_delimeter>(encoding, __root_)) 7125 + first = t1; 7126 + } 7127 + } 7128 + break; 7129 + case 'd': 7130 + // assert(!"__parse_local_name d not implemented"); 7131 + __status_ = not_yet_implemented; 7132 + break; 7133 + default: 7134 + { 7135 + const char*t1 = __parse_name(t, last); 7136 + if (t1 != t) 7137 + { 7138 + // parse but ignore discriminator 7139 + t1 = __parse_discriminator(t1, last); 7140 + if (__make<__nested_delimeter>(encoding, __root_)) 7141 + first = t1; 7142 + } 7143 + } 7144 + break; 7145 + } 7146 + } 7147 + } 7148 + return first; 7149 + } 7150 + 7151 + // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f()) 7152 + // ::= <simple-id> # e.g., ~A<2*N> 7153 + 7154 + const char* 7155 + __demangle_tree::__parse_destructor_name(const char* first, const char* last) 7156 + { 7157 + if (first != last) 7158 + { 7159 + const char* t = __parse_unresolved_type(first, last); 7160 + if (t == first) 7161 + t = __parse_simple_id(first, last); 7162 + if (t != first && __make<__destructor>(__root_)) 7163 + first = t; 7164 + } 7165 + return first; 7166 + } 7167 + 7168 + // <simple-id> ::= <source-name> [ <template-args> ] 7169 + 7170 + const char* 7171 + __demangle_tree::__parse_simple_id(const char* first, const char* last) 7172 + { 7173 + if (first != last) 7174 + { 7175 + const char* t = __parse_source_name(first, last); 7176 + if (t != first) 7177 + first = __parse_template_args(t, last); 7178 + else 7179 + first = t; 7180 + } 7181 + return first; 7182 + } 7183 + 7184 + // <base-unresolved-name> ::= <simple-id> # unresolved name 7185 + // extension ::= <operator-name> # unresolved operator-function-id 7186 + // extension ::= <operator-name> <template-args> # unresolved operator template-id 7187 + // ::= on <operator-name> # unresolved operator-function-id 7188 + // ::= on <operator-name> <template-args> # unresolved operator template-id 7189 + // ::= dn <destructor-name> # destructor or pseudo-destructor; 7190 + // # e.g. ~X or ~X<N-1> 7191 + 7192 + const char* 7193 + __demangle_tree::__parse_base_unresolved_name(const char* first, const char* last) 7194 + { 7195 + if (last - first >= 2) 7196 + { 7197 + if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n') 7198 + { 7199 + if (first[0] == 'o') 7200 + { 7201 + const char* t = __parse_operator_name(first+2, last); 7202 + if (t != first+2) 7203 + first = __parse_template_args(t, last); 7204 + else 7205 + first = t; 7206 + } 7207 + else 7208 + { 7209 + const char* t = __parse_destructor_name(first+2, last); 7210 + if (t != first+2) 7211 + first = t; 7212 + } 7213 + } 7214 + else 7215 + { 7216 + const char* t = __parse_simple_id(first, last); 7217 + if (t == first) 7218 + { 7219 + t = __parse_operator_name(first, last); 7220 + if (t != first) 7221 + t = __parse_template_args(t, last); 7222 + } 7223 + if (t != first) 7224 + first = t; 7225 + } 7226 + } 7227 + return first; 7228 + } 7229 + 7230 + // <unresolved-type> ::= <template-param> 7231 + // ::= <decltype> 7232 + // ::= <substitution> 7233 + 7234 + const char* 7235 + __demangle_tree::__parse_unresolved_type(const char* first, const char* last) 7236 + { 7237 + if (first != last) 7238 + { 7239 + const char* t; 7240 + switch (*first) 7241 + { 7242 + case 'T': 7243 + t = __parse_template_param(first, last); 7244 + if (t != first) 7245 + { 7246 + if (__sub_end_ == __sub_cap_) 7247 + __status_ = memory_alloc_failure; 7248 + else 7249 + { 7250 + *__sub_end_++ = __root_; 7251 + first = t; 7252 + } 7253 + } 7254 + break; 7255 + case 'D': 7256 + t = __parse_decltype(first, last); 7257 + if (t != first) 7258 + { 7259 + if (__sub_end_ == __sub_cap_) 7260 + __status_ = memory_alloc_failure; 7261 + else 7262 + { 7263 + *__sub_end_++ = __root_; 7264 + first = t; 7265 + } 7266 + } 7267 + break; 7268 + case 'S': 7269 + t = __parse_substitution(first, last); 7270 + if (t != first) 7271 + first = t; 7272 + break; 7273 + } 7274 + } 7275 + return first; 7276 + } 7277 + 7278 + // <unresolved-qualifier-level> ::= <source-name> [ <template-args> ] 7279 + 7280 + const char* 7281 + __demangle_tree::__parse_unresolved_qualifier_level(const char* first, const char* last) 7282 + { 7283 + if (first != last) 7284 + { 7285 + const char* t = __parse_source_name(first, last); 7286 + if (t != first) 7287 + first = __parse_template_args(t, last); 7288 + } 7289 + return first; 7290 + } 7291 + 7292 + // <unresolved-name> 7293 + // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> 7294 + // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x 7295 + // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> 7296 + // # A::x, N::y, A<T>::z; "gs" means leading "::" 7297 + // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x 7298 + // # T::N::x /decltype(p)::N::x 7299 + // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> 7300 + 7301 + const char* 7302 + __demangle_tree::__parse_unresolved_name(const char* first, const char* last) 7303 + { 7304 + if (last - first > 2) 7305 + { 7306 + const char* t = first; 7307 + bool global = false; 7308 + if (t[0] == 'g' && t[1] == 's') 7309 + { 7310 + global = true; 7311 + t += 2; 7312 + } 7313 + const char* t2 = __parse_base_unresolved_name(t, last); 7314 + if (t2 != t) 7315 + { 7316 + if (__make<__unresolved_name>(global, (__node*)0, __root_)) 7317 + first = t2; 7318 + } 7319 + else if (last - t > 2 && t[0] == 's' && t[1] == 'r') 7320 + { 7321 + if (!global && t[2] == 'N') 7322 + { 7323 + t2 = __parse_unresolved_type(t+3, last); 7324 + if (t2 != t+3 && t2 != last) 7325 + { 7326 + t = __parse_template_args(t2, last); 7327 + if (t == last) 7328 + return first; 7329 + __node* name = __root_; 7330 + while (*t != 'E') 7331 + { 7332 + t2 = __parse_unresolved_qualifier_level(t, last); 7333 + if (t2 == t || t2 == last) 7334 + return first; 7335 + if (!__make<__nested_delimeter>(name, __root_)) 7336 + return first; 7337 + name = __root_; 7338 + t = t2; 7339 + } 7340 + t2 = __parse_base_unresolved_name(++t, last); 7341 + if (t2 != t && __make<__unresolved_name>(false, name, __root_)) 7342 + first = t2; 7343 + } 7344 + } 7345 + else 7346 + { 7347 + if (!global) 7348 + { 7349 + t2 = __parse_unresolved_type(t+2, last); 7350 + if (t2 != t+2) 7351 + { 7352 + t = t2; 7353 + __node* name = __root_; 7354 + t2 = __parse_base_unresolved_name(t, last); 7355 + if (t2 != t && __make<__unresolved_name>(false, name, __root_)) 7356 + return t2; 7357 + return first; 7358 + } 7359 + } 7360 + t2 = __parse_unresolved_qualifier_level(t+2, last); 7361 + if (t2 != t+2 && t2 != last) 7362 + { 7363 + __node* name = __root_; 7364 + t = t2; 7365 + while (*t != 'E') 7366 + { 7367 + t2 = __parse_unresolved_qualifier_level(t, last); 7368 + if (t2 == t || t2 == last) 7369 + return first; 7370 + if (!__make<__nested_delimeter>(name, __root_)) 7371 + return first; 7372 + name = __root_; 7373 + t = t2; 7374 + } 7375 + t2 = __parse_base_unresolved_name(++t, last); 7376 + if (t2 != t && __make<__unresolved_name>(global, name, __root_)) 7377 + first = t2; 7378 + } 7379 + } 7380 + } 7381 + } 7382 + return first; 7383 + } 7384 + 7385 + // <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter 7386 + // ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters 7387 + // ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _ # L > 0, first parameter 7388 + // ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> 7389 + 7390 + const char* 7391 + __demangle_tree::__parse_function_param(const char* first, const char* last) 7392 + { 7393 + if (last - first >= 3 && *first == 'f') 7394 + { 7395 + if (first[1] == 'p') 7396 + { 7397 + // assert(!"__parse_function_param not implemented"); 7398 + __status_ = not_yet_implemented; 7399 + } 7400 + else if (first[1] == 'L') 7401 + { 7402 + // assert(!"__parse_function_param not implemented"); 7403 + __status_ = not_yet_implemented; 7404 + } 7405 + } 7406 + return first; 7407 + } 7408 + 7409 + // at <type> # alignof (a type) 7410 + 7411 + const char* 7412 + __demangle_tree::__parse_alignof_expr(const char* first, const char* last) 7413 + { 7414 + if (last - first >= 3 && first[0] == 'a' && first[1] == 't') 7415 + { 7416 + const char* t = __parse_type(first+2, last); 7417 + if (t != first+2) 7418 + { 7419 + if (__make<__operator_alignof_expression>(__root_)) 7420 + first = t; 7421 + } 7422 + } 7423 + return first; 7424 + } 7425 + 7426 + // cc <type> <expression> # const_cast<type> (expression) 7427 + 7428 + const char* 7429 + __demangle_tree::__parse_const_cast_expr(const char* first, const char* last) 7430 + { 7431 + if (last - first >= 3 && first[0] == 'c' && first[1] == 'c') 7432 + { 7433 + const char* t = __parse_type(first+2, last); 7434 + if (t != first+2) 7435 + { 7436 + __node* type = __root_; 7437 + const char* t1 = __parse_expression(t, last); 7438 + if (t1 != t) 7439 + { 7440 + if (__make<__const_cast>(type, __root_)) 7441 + first = t1; 7442 + } 7443 + } 7444 + } 7445 + return first; 7446 + } 7447 + 7448 + // cl <expression>+ E # call 7449 + 7450 + const char* 7451 + __demangle_tree::__parse_call_expr(const char* first, const char* last) 7452 + { 7453 + if (last - first >= 4 && first[0] == 'c' && first[1] == 'l') 7454 + { 7455 + const char* t = __parse_expression(first+2, last); 7456 + if (t != first+2) 7457 + { 7458 + if (t == last) 7459 + return first; 7460 + __node* name = __root_; 7461 + __node* args = 0; 7462 + __node* prev = 0; 7463 + while (*t != 'E') 7464 + { 7465 + const char* t1 = __parse_expression(t, last); 7466 + if (t1 == t || t1 == last) 7467 + return first; 7468 + if (!__make<__list>(__root_)) 7469 + return first; 7470 + if (args == 0) 7471 + args = __root_; 7472 + if (prev) 7473 + { 7474 + prev->__right_ = __root_; 7475 + __root_->__size_ = prev->__size_ + 1; 7476 + } 7477 + prev = __root_; 7478 + t = t1; 7479 + } 7480 + ++t; 7481 + if (__make<__call_expr>(name, args)) 7482 + first = t; 7483 + } 7484 + } 7485 + return first; 7486 + } 7487 + 7488 + // cv <type> <expression> # conversion with one argument 7489 + // cv <type> _ <expression>* E # conversion with a different number of arguments 7490 + 7491 + const char* 7492 + __demangle_tree::__parse_conversion_expr(const char* first, const char* last) 7493 + { 7494 + if (last - first >= 3 && first[0] == 'c' && first[1] == 'v') 7495 + { 7496 + const char* t = __parse_type(first+2, last); 7497 + if (t != first+2 && t != last) 7498 + { 7499 + __node* type = __root_; 7500 + __node* args = 0; 7501 + if (*t != '_') 7502 + { 7503 + const char* t1 = __parse_expression(t, last); 7504 + if (t1 == t) 7505 + return first; 7506 + args = __root_; 7507 + t = t1; 7508 + } 7509 + else 7510 + { 7511 + ++t; 7512 + if (t == last) 7513 + return first; 7514 + __node* prev = 0; 7515 + while (*t != 'E') 7516 + { 7517 + const char* t1 = __parse_expression(t, last); 7518 + if (t1 == t || t1 == last) 7519 + return first; 7520 + if (!__make<__list>(__root_)) 7521 + return first; 7522 + if (args == 0) 7523 + args = __root_; 7524 + if (prev) 7525 + { 7526 + prev->__right_ = __root_; 7527 + __root_->__size_ = prev->__size_ + 1; 7528 + } 7529 + prev = __root_; 7530 + t = t1; 7531 + } 7532 + ++t; 7533 + } 7534 + if (__make<__operator_cast>(type, args)) 7535 + first = t; 7536 + } 7537 + } 7538 + return first; 7539 + } 7540 + 7541 + // [gs] da <expression> # delete[] expression 7542 + 7543 + const char* 7544 + __demangle_tree::__parse_delete_array_expr(const char* first, const char* last) 7545 + { 7546 + if (last - first >= 4) 7547 + { 7548 + const char* t = first; 7549 + bool parsed_gs = false; 7550 + if (t[0] == 'g' && t[1] == 's') 7551 + { 7552 + t += 2; 7553 + parsed_gs = true; 7554 + } 7555 + if (t[0] == 'd' && t[1] == 'a') 7556 + { 7557 + t += 2; 7558 + const char* t1 = __parse_expression(t, last); 7559 + if (t1 != t) 7560 + { 7561 + if (__make<__delete_array_expr>(parsed_gs, __root_)) 7562 + first = t1; 7563 + } 7564 + } 7565 + } 7566 + return first; 7567 + } 7568 + 7569 + // dc <type> <expression> # dynamic_cast<type> (expression) 7570 + 7571 + const char* 7572 + __demangle_tree::__parse_dynamic_cast_expr(const char* first, const char* last) 7573 + { 7574 + if (last - first >= 3 && first[0] == 'd' && first[1] == 'c') 7575 + { 7576 + const char* t = __parse_type(first+2, last); 7577 + if (t != first+2) 7578 + { 7579 + __node* type = __root_; 7580 + const char* t1 = __parse_expression(t, last); 7581 + if (t1 != t) 7582 + { 7583 + if (__make<__dynamic_cast>(type, __root_)) 7584 + first = t1; 7585 + } 7586 + } 7587 + } 7588 + return first; 7589 + } 7590 + 7591 + // [gs] dl <expression> # delete expression 7592 + 7593 + const char* 7594 + __demangle_tree::__parse_delete_expr(const char* first, const char* last) 7595 + { 7596 + if (last - first >= 4) 7597 + { 7598 + const char* t = first; 7599 + bool parsed_gs = false; 7600 + if (t[0] == 'g' && t[1] == 's') 7601 + { 7602 + t += 2; 7603 + parsed_gs = true; 7604 + } 7605 + if (t[0] == 'd' && t[1] == 'l') 7606 + { 7607 + t += 2; 7608 + const char* t1 = __parse_expression(t, last); 7609 + if (t1 != t) 7610 + { 7611 + if (__make<__delete_expr>(parsed_gs, __root_)) 7612 + first = t1; 7613 + } 7614 + } 7615 + } 7616 + return first; 7617 + } 7618 + 7619 + // ds <expression> <expression> # expr.*expr 7620 + 7621 + const char* 7622 + __demangle_tree::__parse_dot_star_expr(const char* first, const char* last) 7623 + { 7624 + if (last - first >= 3 && first[0] == 'd' && first[1] == 's') 7625 + { 7626 + const char* t = __parse_expression(first+2, last); 7627 + if (t != first+2) 7628 + { 7629 + __node* expr = __root_; 7630 + const char* t1 = __parse_expression(t, last); 7631 + if (t1 != t) 7632 + { 7633 + if (__make<__dot_star_expr>(expr, __root_)) 7634 + first = t1; 7635 + } 7636 + } 7637 + } 7638 + return first; 7639 + } 7640 + 7641 + // dt <expression> <unresolved-name> # expr.name 7642 + 7643 + const char* 7644 + __demangle_tree::__parse_dot_expr(const char* first, const char* last) 7645 + { 7646 + if (last - first >= 3 && first[0] == 'd' && first[1] == 't') 7647 + { 7648 + const char* t = __parse_expression(first+2, last); 7649 + if (t != first+2) 7650 + { 7651 + __node* expr = __root_; 7652 + const char* t1 = __parse_unresolved_name(t, last); 7653 + if (t1 != t) 7654 + { 7655 + if (__make<__dot_expr>(expr, __root_)) 7656 + first = t1; 7657 + } 7658 + } 7659 + } 7660 + return first; 7661 + } 7662 + 7663 + // mm_ <expression> # prefix -- 7664 + 7665 + const char* 7666 + __demangle_tree::__parse_decrement_expr(const char* first, const char* last) 7667 + { 7668 + if (last - first > 3 && first[0] == 'm' && first[1] == 'm' && first[2] == '_') 7669 + { 7670 + const char* t = __parse_expression(first+3, last); 7671 + if (t != first+3) 7672 + { 7673 + if (__make<__operator_decrement>(true, __root_)) 7674 + first = t; 7675 + } 7676 + } 7677 + return first; 7678 + } 7679 + 7680 + // pp_ <expression> # prefix ++ 7681 + 7682 + const char* 7683 + __demangle_tree::__parse_increment_expr(const char* first, const char* last) 7684 + { 7685 + if (last - first > 3 && first[0] == 'p' && first[1] == 'p' && first[2] == '_') 7686 + { 7687 + const char* t = __parse_expression(first+3, last); 7688 + if (t != first+3) 7689 + { 7690 + if (__make<__operator_increment>(true, __root_)) 7691 + first = t; 7692 + } 7693 + } 7694 + return first; 7695 + } 7696 + 7697 + // [gs] nw <expression>* _ <type> E # new (expr-list) type 7698 + // [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 7699 + // [gs] na <expression>* _ <type> E # new[] (expr-list) type 7700 + // [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 7701 + // <initializer> ::= pi <expression>* E # parenthesized initialization 7702 + 7703 + const char* 7704 + __demangle_tree::__parse_new_expr(const char* first, const char* last) 7705 + { 7706 + if (last - first >= 4) 7707 + { 7708 + const char* t = first; 7709 + bool parsed_gs = false; 7710 + if (t[0] == 'g' && t[1] == 's') 7711 + { 7712 + t += 2; 7713 + parsed_gs = true; 7714 + } 7715 + if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a')) 7716 + { 7717 + bool is_array = t[1] == 'a'; 7718 + t += 2; 7719 + if (t == last) 7720 + return first; 7721 + __node* expr = 0; 7722 + __node* prev = 0; 7723 + while (*t != '_') 7724 + { 7725 + const char* t1 = __parse_expression(t, last); 7726 + if (t1 == t || t1 == last) 7727 + return first; 7728 + if (!__make<__list>(__root_)) 7729 + return first; 7730 + if (expr == 0) 7731 + expr = __root_; 7732 + if (prev) 7733 + { 7734 + prev->__right_ = __root_; 7735 + __root_->__size_ = prev->__size_ + 1; 7736 + } 7737 + prev = __root_; 7738 + t = t1; 7739 + } 7740 + ++t; 7741 + const char* t1 = __parse_type(t, last); 7742 + if (t1 == t || t1 == last) 7743 + return first; 7744 + t = t1; 7745 + __node* type = __root_; 7746 + __node* init = 0; 7747 + prev = 0; 7748 + bool has_init = false; 7749 + if (last - t >= 3 && t[0] == 'p' && t[1] == 'i') 7750 + { 7751 + t += 2; 7752 + has_init = true; 7753 + while (*t != 'E') 7754 + { 7755 + t1 = __parse_expression(t, last); 7756 + if (t1 == t || t1 == last) 7757 + return first; 7758 + if (!__make<__list>(__root_)) 7759 + return first; 7760 + if (init == 0) 7761 + init = __root_; 7762 + if (prev) 7763 + { 7764 + prev->__right_ = __root_; 7765 + __root_->__size_ = prev->__size_ + 1; 7766 + } 7767 + prev = __root_; 7768 + t = t1; 7769 + } 7770 + } 7771 + if (*t != 'E') 7772 + return first; 7773 + if (__make<__new_expr>(parsed_gs, is_array, has_init, 7774 + expr, type, init)) 7775 + first = t; 7776 + } 7777 + } 7778 + return first; 7779 + } 7780 + 7781 + // pt <expression> <unresolved-name> # expr->name 7782 + 7783 + const char* 7784 + __demangle_tree::__parse_arrow_expr(const char* first, const char* last) 7785 + { 7786 + if (last - first >= 3 && first[0] == 'p' && first[1] == 't') 7787 + { 7788 + const char* t = __parse_expression(first+2, last); 7789 + if (t != first+2) 7790 + { 7791 + __node* expr = __root_; 7792 + const char* t1 = __parse_unresolved_name(t, last); 7793 + if (t1 != t) 7794 + { 7795 + if (__make<__arrow_expr>(expr, __root_)) 7796 + first = t1; 7797 + } 7798 + } 7799 + } 7800 + return first; 7801 + } 7802 + 7803 + // rc <type> <expression> # reinterpret_cast<type> (expression) 7804 + 7805 + const char* 7806 + __demangle_tree::__parse_reinterpret_cast_expr(const char* first, const char* last) 7807 + { 7808 + if (last - first >= 3 && first[0] == 'r' && first[1] == 'c') 7809 + { 7810 + const char* t = __parse_type(first+2, last); 7811 + if (t != first+2) 7812 + { 7813 + __node* type = __root_; 7814 + const char* t1 = __parse_expression(t, last); 7815 + if (t1 != t) 7816 + { 7817 + if (__make<__reinterpret_cast>(type, __root_)) 7818 + first = t1; 7819 + } 7820 + } 7821 + } 7822 + return first; 7823 + } 7824 + 7825 + // sc <type> <expression> # static_cast<type> (expression) 7826 + 7827 + const char* 7828 + __demangle_tree::__parse_static_cast_expr(const char* first, const char* last) 7829 + { 7830 + if (last - first >= 3 && first[0] == 's' && first[1] == 'c') 7831 + { 7832 + const char* t = __parse_type(first+2, last); 7833 + if (t != first+2) 7834 + { 7835 + __node* type = __root_; 7836 + const char* t1 = __parse_expression(t, last); 7837 + if (t1 != t) 7838 + { 7839 + if (__make<__static_cast>(type, __root_)) 7840 + first = t1; 7841 + } 7842 + } 7843 + } 7844 + return first; 7845 + } 7846 + 7847 + // st <type> # sizeof (a type) 7848 + 7849 + const char* 7850 + __demangle_tree::__parse_sizeof_type_expr(const char* first, const char* last) 7851 + { 7852 + if (last - first >= 3 && first[0] == 's' && first[1] == 't') 7853 + { 7854 + const char* t = __parse_type(first+2, last); 7855 + if (t != first+2) 7856 + { 7857 + if (__make<__operator_sizeof_expression>(__root_)) 7858 + first = t; 7859 + } 7860 + } 7861 + return first; 7862 + } 7863 + 7864 + // sZ <template-param> # size of a parameter pack 7865 + 7866 + const char* 7867 + __demangle_tree::__parse_sizeof_param_pack_expr(const char* first, const char* last) 7868 + { 7869 + if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T') 7870 + { 7871 + const char* t = __parse_template_param(first+2, last); 7872 + if (t != first+2) 7873 + { 7874 + if (__make<__operator_sizeof_param_pack>(__root_)) 7875 + first = t; 7876 + } 7877 + } 7878 + return first; 7879 + } 7880 + 7881 + // sZ <function-param> # size of a function parameter pack 7882 + 7883 + const char* 7884 + __demangle_tree::__parse_sizeof_function_param_pack_expr(const char* first, const char* last) 7885 + { 7886 + if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f') 7887 + { 7888 + const char* t = __parse_function_param(first+2, last); 7889 + if (t != first+2) 7890 + { 7891 + if (__make<__operator_sizeof_param_pack>(__root_)) 7892 + first = t; 7893 + } 7894 + } 7895 + return first; 7896 + } 7897 + 7898 + // sp <expression> # pack expansion 7899 + 7900 + const char* 7901 + __demangle_tree::__parse_pack_expansion(const char* first, const char* last) 7902 + { 7903 + if (last - first >= 3 && first[0] == 's' && first[1] == 'p') 7904 + { 7905 + const char* t = __parse_expression(first+2, last); 7906 + if (t != first+2) 7907 + { 7908 + if (__make<__pack_expansion>(__root_)) 7909 + first = t; 7910 + } 7911 + } 7912 + return first; 7913 + } 7914 + 7915 + // te <expression> # typeid (expression) 7916 + // ti <type> # typeid (type) 7917 + 7918 + const char* 7919 + __demangle_tree::__parse_typeid_expr(const char* first, const char* last) 7920 + { 7921 + if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i')) 7922 + { 7923 + const char* t; 7924 + if (first[1] == 'e') 7925 + t = __parse_expression(first+2, last); 7926 + else 7927 + t = __parse_type(first+2, last); 7928 + if (t != first+2) 7929 + { 7930 + if (__make<__typeid>(__root_)) 7931 + first = t; 7932 + } 7933 + } 7934 + return first; 7935 + } 7936 + 7937 + // tw <expression> # throw expression 7938 + 7939 + const char* 7940 + __demangle_tree::__parse_throw_expr(const char* first, const char* last) 7941 + { 7942 + if (last - first >= 3 && first[0] == 't' && first[1] == 'w') 7943 + { 7944 + const char* t = __parse_expression(first+2, last); 7945 + if (t != first+2) 7946 + { 7947 + if (__make<__throw>(__root_)) 7948 + first = t; 7949 + } 7950 + } 7951 + return first; 7952 + } 7953 + 7954 + // <expression> ::= <unary operator-name> <expression> 7955 + // ::= <binary operator-name> <expression> <expression> 7956 + // ::= <ternary operator-name> <expression> <expression> <expression> 7957 + // ::= cl <expression>+ E # call 7958 + // ::= cv <type> <expression> # conversion with one argument 7959 + // ::= cv <type> _ <expression>* E # conversion with a different number of arguments 7960 + // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type 7961 + // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 7962 + // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type 7963 + // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 7964 + // ::= [gs] dl <expression> # delete expression 7965 + // ::= [gs] da <expression> # delete[] expression 7966 + // ::= pp_ <expression> # prefix ++ 7967 + // ::= mm_ <expression> # prefix -- 7968 + // ::= ti <type> # typeid (type) 7969 + // ::= te <expression> # typeid (expression) 7970 + // ::= dc <type> <expression> # dynamic_cast<type> (expression) 7971 + // ::= sc <type> <expression> # static_cast<type> (expression) 7972 + // ::= cc <type> <expression> # const_cast<type> (expression) 7973 + // ::= rc <type> <expression> # reinterpret_cast<type> (expression) 7974 + // ::= st <type> # sizeof (a type) 7975 + // ::= at <type> # alignof (a type) 7976 + // ::= <template-param> 7977 + // ::= <function-param> 7978 + // ::= dt <expression> <unresolved-name> # expr.name 7979 + // ::= pt <expression> <unresolved-name> # expr->name 7980 + // ::= ds <expression> <expression> # expr.*expr 7981 + // ::= sZ <template-param> # size of a parameter pack 7982 + // ::= sZ <function-param> # size of a function parameter pack 7983 + // ::= sp <expression> # pack expansion 7984 + // ::= tw <expression> # throw expression 7985 + // ::= tr # throw with no operand (rethrow) 7986 + // ::= <unresolved-name> # f(p), N::f(p), ::f(p), 7987 + // # freestanding dependent name (e.g., T::x), 7988 + // # objectless nonstatic member reference 7989 + // ::= <expr-primary> 7990 + 7991 + const char* 7992 + __demangle_tree::__parse_expression(const char* first, const char* last) 7993 + { 7994 + if (last - first >= 2) 7995 + { 7996 + const char* t = first; 7997 + bool parsed_gs = false; 7998 + if (last - first >= 4 && t[0] == 'g' && t[1] == 's') 7999 + { 8000 + t += 2; 8001 + parsed_gs = true; 8002 + } 8003 + switch (*t) 8004 + { 8005 + case 'L': 8006 + t = __parse_expr_primary(first, last); 8007 + break; 8008 + case 'T': 8009 + t = __parse_template_param(first, last); 8010 + break; 8011 + case 'f': 8012 + t = __parse_function_param(first, last); 8013 + break; 8014 + case 'a': 8015 + if (t[1] == 't') 8016 + t = __parse_alignof_expr(first, last); 8017 + break; 8018 + case 'c': 8019 + switch (t[1]) 8020 + { 8021 + case 'c': 8022 + t = __parse_const_cast_expr(first, last); 8023 + break; 8024 + case 'l': 8025 + t = __parse_call_expr(first, last); 8026 + break; 8027 + case 'v': 8028 + t = __parse_conversion_expr(first, last); 8029 + break; 8030 + } 8031 + break; 8032 + case 'd': 8033 + switch (t[1]) 8034 + { 8035 + case 'a': 8036 + t = __parse_delete_array_expr(first, last); 8037 + break; 8038 + case 'c': 8039 + t = __parse_dynamic_cast_expr(first, last); 8040 + break; 8041 + case 'l': 8042 + t = __parse_delete_expr(first, last); 8043 + break; 8044 + case 's': 8045 + t = __parse_dot_star_expr(first, last); 8046 + break; 8047 + case 't': 8048 + t = __parse_dot_expr(first, last); 8049 + break; 8050 + } 8051 + break; 8052 + case 'm': 8053 + t = __parse_decrement_expr(first, last); 8054 + break; 8055 + case 'n': 8056 + switch (t[1]) 8057 + { 8058 + case 'a': 8059 + case 'w': 8060 + t = __parse_new_expr(first, last); 8061 + break; 8062 + } 8063 + break; 8064 + case 'p': 8065 + switch (t[1]) 8066 + { 8067 + case 'p': 8068 + t = __parse_increment_expr(first, last); 8069 + break; 8070 + case 't': 8071 + t = __parse_arrow_expr(first, last); 8072 + break; 8073 + } 8074 + break; 8075 + case 'r': 8076 + t = __parse_reinterpret_cast_expr(first, last); 8077 + break; 8078 + case 's': 8079 + switch (t[1]) 8080 + { 8081 + case 'c': 8082 + t = __parse_static_cast_expr(first, last); 8083 + break; 8084 + case 'p': 8085 + t = __parse_pack_expansion(first, last); 8086 + break; 8087 + case 't': 8088 + t = __parse_sizeof_type_expr(first, last); 8089 + break; 8090 + case 'Z': 8091 + if (last - t >= 3) 8092 + { 8093 + switch (t[2]) 8094 + { 8095 + case 'T': 8096 + t = __parse_sizeof_param_pack_expr(first, last); 8097 + break; 8098 + case 'f': 8099 + t = __parse_sizeof_function_param_pack_expr(first, last); 8100 + break; 8101 + } 8102 + } 8103 + break; 8104 + } 8105 + break; 8106 + case 't': 8107 + switch (t[1]) 8108 + { 8109 + case 'e': 8110 + case 'i': 8111 + t = __parse_typeid_expr(first, last); 8112 + break; 8113 + case 'r': 8114 + if (__make<__rethrow>()) 8115 + t = first +2; 8116 + break; 8117 + case 'w': 8118 + t = __parse_throw_expr(first, last); 8119 + break; 8120 + } 8121 + break; 8122 + } 8123 + if ((!parsed_gs && t == first) || (parsed_gs && t == first+2)) 8124 + { 8125 + int op; 8126 + t = __parse_operator_name(first, last, &op); 8127 + if (t == first) 8128 + first = __parse_unresolved_name(first, last); 8129 + else 8130 + first = t; 8131 + } 8132 + else 8133 + first = t; 8134 + } 8135 + return first; 8136 + } 8137 + 8138 + // <array-type> ::= A <positive dimension number> _ <element type> 8139 + // ::= A [<dimension expression>] _ <element type> 8140 + 8141 + const char* 8142 + __demangle_tree::__parse_array_type(const char* first, const char* last) 8143 + { 8144 + if (first != last && *first == 'A' && first+1 != last) 8145 + { 8146 + if (first[1] == '_') 8147 + { 8148 + const char* t = __parse_type(first+2, last); 8149 + if (t != first+2) 8150 + { 8151 + if (__make<__array>(__root_)) 8152 + first = t; 8153 + } 8154 + } 8155 + else if ('1' <= first[1] && first[1] <= '9') 8156 + { 8157 + size_t dim = static_cast<size_t>(first[1] - '0'); 8158 + const char* t = first+2; 8159 + for (; t != last && isdigit(*t); ++t) 8160 + dim = dim * 10 + static_cast<size_t>(*t - '0'); 8161 + if (t != last && *t == '_') 8162 + { 8163 + const char* t2 = __parse_type(t+1, last); 8164 + if (t2 != t+1) 8165 + { 8166 + if (__make<__array>(__root_, dim)) 8167 + first = t2; 8168 + } 8169 + } 8170 + } 8171 + else 8172 + { 8173 + const char* t = __parse_expression(first+1, last); 8174 + if (t != first+1 && t != last && *t == '_') 8175 + { 8176 + __node* dim = __root_; 8177 + const char* t2 = __parse_type(++t, last); 8178 + if (t2 != t) 8179 + { 8180 + if (__make<__array>(__root_, dim)) 8181 + first = t2; 8182 + } 8183 + } 8184 + } 8185 + } 8186 + return first; 8187 + } 8188 + 8189 + // <class-enum-type> ::= <name> 8190 + 8191 + const char* 8192 + __demangle_tree::__parse_class_enum_type(const char* first, const char* last) 8193 + { 8194 + return __parse_name(first, last); 8195 + } 8196 + 8197 + // <pointer-to-member-type> ::= M <class type> <member type> 8198 + 8199 + const char* 8200 + __demangle_tree::__parse_pointer_to_member_type(const char* first, const char* last) 8201 + { 8202 + if (first != last && *first == 'M') 8203 + { 8204 + const char* t = __parse_type(first+1, last); 8205 + if (t != first+1) 8206 + { 8207 + __node* class_type = __root_; 8208 + const char* t2 = __parse_type(t, last, true, true); 8209 + if (t2 != t) 8210 + { 8211 + if (__make<__pointer_to_member_type>(class_type, __root_)) 8212 + first = t2; 8213 + } 8214 + } 8215 + } 8216 + return first; 8217 + } 8218 + 8219 + // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) 8220 + // ::= DT <expression> E # decltype of an expression (C++0x) 8221 + 8222 + const char* 8223 + __demangle_tree::__parse_decltype(const char* first, const char* last) 8224 + { 8225 + if (last - first >= 4 && first[0] == 'D') 8226 + { 8227 + switch (first[1]) 8228 + { 8229 + case 't': 8230 + case 'T': 8231 + { 8232 + const char* t = __parse_expression(first+2, last); 8233 + if (t != first+2 && t != last && *t == 'E') 8234 + { 8235 + if (__make<__decltype_node>(__root_)) 8236 + first = t+1; 8237 + } 8238 + } 8239 + break; 8240 + } 8241 + } 8242 + return first; 8243 + } 8244 + 8245 + // <template-param> ::= T_ # first template parameter 8246 + // ::= T <parameter-2 non-negative number> _ 8247 + 8248 + const char* 8249 + __demangle_tree::__parse_template_param(const char* first, const char* last) 8250 + { 8251 + if (last - first >= 2) 8252 + { 8253 + if (*first == 'T') 8254 + { 8255 + if (first[1] == '_') 8256 + { 8257 + if (__t_begin_ != __t_end_) 8258 + { 8259 + if (__make<__sub>(*__t_begin_)) 8260 + first += 2; 8261 + } 8262 + else 8263 + { 8264 + if (__make<__sub>(size_t(0))) 8265 + { 8266 + first += 2; 8267 + __fix_forward_references_ = true; 8268 + } 8269 + } 8270 + } 8271 + else if (isdigit(first[1])) 8272 + { 8273 + const char* t = first+1; 8274 + size_t sub = static_cast<size_t>(*t - '0'); 8275 + for (++t; t != last && isdigit(*t); ++t) 8276 + { 8277 + sub *= 10; 8278 + sub += static_cast<size_t>(*t - '0'); 8279 + } 8280 + if (t == last || *t != '_') 8281 + return first; 8282 + ++sub; 8283 + if (sub < static_cast<size_t>(__t_end_ - __t_begin_)) 8284 + { 8285 + if (__make<__sub>(__t_begin_[sub])) 8286 + first = t+1; 8287 + } 8288 + else 8289 + { 8290 + if (__make<__sub>(sub)) 8291 + { 8292 + first = t+1; 8293 + __fix_forward_references_ = true; 8294 + } 8295 + } 8296 + } 8297 + } 8298 + } 8299 + return first; 8300 + } 8301 + 8302 + // extension: 8303 + // <vector-type> ::= Dv <positive dimension number> _ 8304 + // <extended element type> 8305 + // ::= Dv [<dimension expression>] _ <element type> 8306 + // <extended element type> ::= <element type> 8307 + // ::= p # AltiVec vector pixel 8308 + 8309 + const char* 8310 + __demangle_tree::__parse_vector_type(const char* first, const char* last) 8311 + { 8312 + if (last - first > 3 && first[0] == 'D' && first[1] == 'v') 8313 + { 8314 + if ('1' <= first[2] && first[2] <= '9') 8315 + { 8316 + const char* t = first+3; 8317 + while (*t != '_') 8318 + { 8319 + if (!isdigit(*t) || ++t == last) 8320 + return first; 8321 + } 8322 + const char* num = first + 2; 8323 + size_t sz = static_cast<size_t>(t - num); 8324 + if (++t != last) 8325 + { 8326 + if (*t != 'p') 8327 + { 8328 + const char* t1 = __parse_type(t, last); 8329 + if (t1 != t) 8330 + { 8331 + if (__make<__vector_type>(__root_, num, sz)) 8332 + first = t1; 8333 + } 8334 + } 8335 + else 8336 + { 8337 + ++t; 8338 + if (__make<__vector_type>((__node*)0, num, sz)) 8339 + first = t; 8340 + } 8341 + } 8342 + } 8343 + else 8344 + { 8345 + __node* num = 0; 8346 + const char* t1 = first+2; 8347 + if (*t1 != '_') 8348 + { 8349 + const char* t = __parse_expression(t1, last); 8350 + if (t != t1) 8351 + num = __root_; 8352 + t1 = t; 8353 + } 8354 + if (t1 != last && *t1 == '_' && ++t1 != last) 8355 + { 8356 + const char* t = __parse_type(t1, last); 8357 + if (t != t1) 8358 + { 8359 + if (__make<__vector_type>(__root_, num)) 8360 + first = t; 8361 + } 8362 + } 8363 + } 8364 + } 8365 + return first; 8366 + } 8367 + 8368 + // <type> ::= <builtin-type> 8369 + // ::= <function-type> 8370 + // ::= <class-enum-type> 8371 + // ::= <array-type> 8372 + // ::= <pointer-to-member-type> 8373 + // ::= <template-param> 8374 + // ::= <template-template-param> <template-args> 8375 + // ::= <decltype> 8376 + // ::= <substitution> 8377 + // ::= <CV-qualifiers> <type> 8378 + // ::= P <type> # pointer-to 8379 + // ::= R <type> # reference-to 8380 + // ::= O <type> # rvalue reference-to (C++0x) 8381 + // ::= C <type> # complex pair (C 2000) 8382 + // ::= G <type> # imaginary (C 2000) 8383 + // ::= Dp <type> # pack expansion (C++0x) 8384 + // ::= U <source-name> <type> # vendor extended type qualifier 8385 + // extension := <vector-type> # <vector-type> starts with Dv 8386 + 8387 + const char* 8388 + __demangle_tree::__parse_type(const char* first, const char* last, 8389 + bool try_to_parse_template_args, 8390 + bool look_for_ref_quals) 8391 + { 8392 + unsigned cv = 0; 8393 + const char* t = __parse_cv_qualifiers(first, last, cv, look_for_ref_quals); 8394 + if (t != first) 8395 + { 8396 + const char* t2 = __parse_type(t, last, try_to_parse_template_args); 8397 + if (t2 != t) 8398 + { 8399 + if (__make<__cv_qualifiers>(cv, __root_)) 8400 + { 8401 + if (__sub_end_ == __sub_cap_) 8402 + __status_ = memory_alloc_failure; 8403 + else 8404 + { 8405 + *__sub_end_++ = __root_; 8406 + first = t2; 8407 + } 8408 + } 8409 + } 8410 + return first; 8411 + } 8412 + if (first != last) 8413 + { 8414 + switch (*first) 8415 + { 8416 + case 'A': 8417 + t = __parse_array_type(first, last); 8418 + if (t != first) 8419 + { 8420 + if (__sub_end_ == __sub_cap_) 8421 + __status_ = memory_alloc_failure; 8422 + else 8423 + { 8424 + *__sub_end_++ = __root_; 8425 + first = t; 8426 + } 8427 + } 8428 + break; 8429 + case 'C': 8430 + t = __parse_type(first+1, last, try_to_parse_template_args); 8431 + if (t != first+1) 8432 + { 8433 + if (__make<__d_complex>(__root_)) 8434 + { 8435 + if (__sub_end_ == __sub_cap_) 8436 + __status_ = memory_alloc_failure; 8437 + else 8438 + { 8439 + *__sub_end_++ = __root_; 8440 + first = t; 8441 + } 8442 + } 8443 + return first; 8444 + } 8445 + break; 8446 + case 'F': 8447 + t = __parse_function_type(first, last); 8448 + if (t != first) 8449 + { 8450 + if (__sub_end_ == __sub_cap_) 8451 + __status_ = memory_alloc_failure; 8452 + else 8453 + { 8454 + *__sub_end_++ = __root_; 8455 + first = t; 8456 + } 8457 + } 8458 + break; 8459 + case 'G': 8460 + t = __parse_type(first+1, last, try_to_parse_template_args); 8461 + if (t != first+1) 8462 + { 8463 + if (__make<__imaginary>(__root_)) 8464 + { 8465 + if (__sub_end_ == __sub_cap_) 8466 + __status_ = memory_alloc_failure; 8467 + else 8468 + { 8469 + *__sub_end_++ = __root_; 8470 + first = t; 8471 + } 8472 + } 8473 + return first; 8474 + } 8475 + break; 8476 + case 'M': 8477 + t = __parse_pointer_to_member_type(first, last); 8478 + if (t != first) 8479 + { 8480 + if (__sub_end_ == __sub_cap_) 8481 + __status_ = memory_alloc_failure; 8482 + else 8483 + { 8484 + *__sub_end_++ = __root_; 8485 + first = t; 8486 + } 8487 + } 8488 + break; 8489 + case 'O': 8490 + t = __parse_type(first+1, last, try_to_parse_template_args); 8491 + if (t != first+1) 8492 + { 8493 + if (__make<__rvalue_reference_to>(__root_)) 8494 + { 8495 + if (__sub_end_ == __sub_cap_) 8496 + __status_ = memory_alloc_failure; 8497 + else 8498 + { 8499 + *__sub_end_++ = __root_; 8500 + first = t; 8501 + } 8502 + } 8503 + return first; 8504 + } 8505 + break; 8506 + case 'P': 8507 + t = __parse_type(first+1, last, try_to_parse_template_args); 8508 + if (t != first+1) 8509 + { 8510 + if (__make<__pointer_to>(__root_)) 8511 + { 8512 + if (__sub_end_ == __sub_cap_) 8513 + __status_ = memory_alloc_failure; 8514 + else 8515 + { 8516 + *__sub_end_++ = __root_; 8517 + first = t; 8518 + } 8519 + } 8520 + return first; 8521 + } 8522 + break; 8523 + case 'R': 8524 + t = __parse_type(first+1, last, try_to_parse_template_args); 8525 + if (t != first+1) 8526 + { 8527 + if (__make<__lvalue_reference_to>(__root_)) 8528 + { 8529 + if (__sub_end_ == __sub_cap_) 8530 + __status_ = memory_alloc_failure; 8531 + else 8532 + { 8533 + *__sub_end_++ = __root_; 8534 + first = t; 8535 + } 8536 + } 8537 + return first; 8538 + } 8539 + break; 8540 + case 'T': 8541 + t = __parse_template_param(first, last); 8542 + if (t != first) 8543 + { 8544 + if (__sub_end_ == __sub_cap_) 8545 + __status_ = memory_alloc_failure; 8546 + else 8547 + { 8548 + *__sub_end_++ = __root_; 8549 + if (try_to_parse_template_args) 8550 + { 8551 + const char* t2 = __parse_template_args(t, last); 8552 + if (t2 != t) 8553 + { 8554 + if (__sub_end_ < __sub_cap_) 8555 + { 8556 + *__sub_end_++ = __root_; 8557 + first = t2; 8558 + } 8559 + else 8560 + __status_ = memory_alloc_failure; 8561 + } 8562 + else 8563 + { 8564 + first = t; 8565 + } 8566 + } 8567 + else 8568 + { 8569 + first = t; 8570 + } 8571 + } 8572 + } 8573 + break; 8574 + case 'U': 8575 + if (first+1 != last) 8576 + { 8577 + t = __parse_source_name(first+1, last); 8578 + if (t != first+1) 8579 + { 8580 + __node* name = __root_; 8581 + const char* t2 = __parse_type(t, last, try_to_parse_template_args); 8582 + if (t2 != t) 8583 + { 8584 + if (__make<__extended_qualifier>(name, __root_)) 8585 + { 8586 + if (__sub_end_ == __sub_cap_) 8587 + __status_ = memory_alloc_failure; 8588 + else 8589 + { 8590 + *__sub_end_++ = __root_; 8591 + first = t2; 8592 + } 8593 + } 8594 + return first; 8595 + } 8596 + } 8597 + } 8598 + break; 8599 + case 'S': 8600 + if (first+1 != last && first[1] == 't') 8601 + { 8602 + t = __parse_class_enum_type(first, last); 8603 + if (t != first) 8604 + { 8605 + if (__sub_end_ == __sub_cap_) 8606 + __status_ = memory_alloc_failure; 8607 + else 8608 + { 8609 + *__sub_end_++ = __root_; 8610 + first = t; 8611 + } 8612 + } 8613 + } 8614 + else 8615 + { 8616 + t = __parse_substitution(first, last); 8617 + if (t != first) 8618 + { 8619 + first = t; 8620 + // Parsed a substitution. If the substitution is a 8621 + // <template-param> it might be followed by <template-args>. 8622 + t = __parse_template_args(first, last); 8623 + if (t != first) 8624 + { 8625 + // Need to create substitution for <template-template-param> <template-args> 8626 + if (__sub_end_ == __sub_cap_) 8627 + __status_ = memory_alloc_failure; 8628 + else 8629 + { 8630 + *__sub_end_++ = __root_; 8631 + first = t; 8632 + } 8633 + } 8634 + } 8635 + } 8636 + break; 8637 + case 'D': 8638 + if (first+1 != last) 8639 + { 8640 + switch (first[1]) 8641 + { 8642 + case 'p': 8643 + t = __parse_type(first+2, last, try_to_parse_template_args); 8644 + if (t != first+1) 8645 + { 8646 + if (__make<__pack_expansion>(__root_)) 8647 + { 8648 + if (__sub_end_ == __sub_cap_) 8649 + __status_ = memory_alloc_failure; 8650 + else 8651 + { 8652 + *__sub_end_++ = __root_; 8653 + first = t; 8654 + } 8655 + } 8656 + return first; 8657 + } 8658 + break; 8659 + case 't': 8660 + case 'T': 8661 + t = __parse_decltype(first, last); 8662 + if (t != first) 8663 + { 8664 + if (__sub_end_ == __sub_cap_) 8665 + __status_ = memory_alloc_failure; 8666 + else 8667 + { 8668 + *__sub_end_++ = __root_; 8669 + first = t; 8670 + } 8671 + return first; 8672 + } 8673 + break; 8674 + case 'v': 8675 + t = __parse_vector_type(first, last); 8676 + if (t != first) 8677 + { 8678 + if (__sub_end_ == __sub_cap_) 8679 + __status_ = memory_alloc_failure; 8680 + else 8681 + { 8682 + *__sub_end_++ = __root_; 8683 + first = t; 8684 + } 8685 + return first; 8686 + } 8687 + break; 8688 + } 8689 + } 8690 + // drop through 8691 + default: 8692 + // must check for builtin-types before class-enum-types to avoid 8693 + // ambiguities with operator-names 8694 + t = __parse_builtin_type(first, last); 8695 + if (t != first) 8696 + { 8697 + first = t; 8698 + } 8699 + else 8700 + { 8701 + t = __parse_class_enum_type(first, last); 8702 + if (t != first) 8703 + { 8704 + if (__sub_end_ == __sub_cap_) 8705 + __status_ = memory_alloc_failure; 8706 + else 8707 + { 8708 + *__sub_end_++ = __root_; 8709 + first = t; 8710 + } 8711 + } 8712 + } 8713 + break; 8714 + } 8715 + } 8716 + return first; 8717 + } 8718 + 8719 + // <number> ::= [n] <non-negative decimal integer> 8720 + 8721 + const char* 8722 + __demangle_tree::__parse_number(const char* first, const char* last) 8723 + { 8724 + if (first != last) 8725 + { 8726 + const char* t = first; 8727 + if (*t == 'n') 8728 + ++t; 8729 + if (t != last) 8730 + { 8731 + if (*t == '0') 8732 + { 8733 + first = t+1; 8734 + } 8735 + else if ('1' <= *t && *t <= '9') 8736 + { 8737 + first = t+1; 8738 + while (first != last && isdigit(*first)) 8739 + ++first; 8740 + } 8741 + } 8742 + } 8743 + return first; 8744 + } 8745 + 8746 + // <call-offset> ::= h <nv-offset> _ 8747 + // ::= v <v-offset> _ 8748 + // 8749 + // <nv-offset> ::= <offset number> 8750 + // # non-virtual base override 8751 + // 8752 + // <v-offset> ::= <offset number> _ <virtual offset number> 8753 + // # virtual base override, with vcall offset 8754 + 8755 + const char* 8756 + __demangle_tree::__parse_call_offset(const char* first, const char* last) 8757 + { 8758 + if (first != last) 8759 + { 8760 + switch (*first) 8761 + { 8762 + case 'h': 8763 + { 8764 + const char* t = __parse_number(first + 1, last); 8765 + if (t != first + 1 && t != last && *t == '_') 8766 + first = t + 1; 8767 + } 8768 + break; 8769 + case 'v': 8770 + { 8771 + const char* t = __parse_number(first + 1, last); 8772 + if (t != first + 1 && t != last && *t == '_') 8773 + { 8774 + const char* t2 = __parse_number(++t, last); 8775 + if (t2 != t && t2 != last && *t2 == '_') 8776 + first = t2 + 1; 8777 + } 8778 + } 8779 + break; 8780 + } 8781 + } 8782 + return first; 8783 + } 8784 + 8785 + // <special-name> ::= TV <type> # virtual table 8786 + // ::= TT <type> # VTT structure (construction vtable index) 8787 + // ::= TI <type> # typeinfo structure 8788 + // ::= TS <type> # typeinfo name (null-terminated byte string) 8789 + // ::= Tc <call-offset> <call-offset> <base encoding> 8790 + // # base is the nominal target function of thunk 8791 + // # first call-offset is 'this' adjustment 8792 + // # second call-offset is result adjustment 8793 + // ::= T <call-offset> <base encoding> 8794 + // # base is the nominal target function of thunk 8795 + // ::= GV <object name> # Guard variable for one-time initialization 8796 + // # No <type> 8797 + // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 8798 + // extension ::= GR <object name> # reference temporary for object 8799 + 8800 + const char* 8801 + __demangle_tree::__parse_special_name(const char* first, const char* last) 8802 + { 8803 + if (last - first > 2) 8804 + { 8805 + const char* t; 8806 + switch (*first) 8807 + { 8808 + case 'T': 8809 + switch (first[1]) 8810 + { 8811 + case 'V': 8812 + // TV <type> # virtual table 8813 + t = __parse_type(first+2, last); 8814 + if (t != first+2 && __make<__vtable>(__root_)) 8815 + first = t; 8816 + break; 8817 + case 'T': 8818 + // TT <type> # VTT structure (construction vtable index) 8819 + t = __parse_type(first+2, last); 8820 + if (t != first+2 && __make<__VTT>(__root_)) 8821 + first = t; 8822 + break; 8823 + case 'I': 8824 + // TI <type> # typeinfo structure 8825 + t = __parse_type(first+2, last); 8826 + if (t != first+2 && __make<__typeinfo>(__root_)) 8827 + first = t; 8828 + break; 8829 + case 'S': 8830 + // TS <type> # typeinfo name (null-terminated byte string) 8831 + t = __parse_type(first+2, last); 8832 + if (t != first+2 && __make<__typeinfo_name>(__root_)) 8833 + first = t; 8834 + break; 8835 + case 'c': 8836 + // Tc <call-offset> <call-offset> <base encoding> 8837 + { 8838 + const char* t0 = __parse_call_offset(first+2, last); 8839 + if (t0 == first+2) 8840 + break; 8841 + const char* t1 = __parse_call_offset(t0, last); 8842 + if (t1 == t0) 8843 + break; 8844 + t = __parse_encoding(t1, last); 8845 + if (t != t1 && __make<__covariant_return_thunk>(__root_)) 8846 + first = t; 8847 + } 8848 + break; 8849 + case 'C': 8850 + // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 8851 + t = __parse_type(first+2, last); 8852 + if (t != first+2) 8853 + { 8854 + __node* op1 = __root_; 8855 + const char* t0 = __parse_number(t, last); 8856 + if (t0 != t && t0 != last && *t0 == '_') 8857 + { 8858 + const char* t1 = __parse_type(++t0, last); 8859 + if (t1 != t0) 8860 + { 8861 + if (__make<__construction_vtable>(__root_, op1)) 8862 + first = t1; 8863 + } 8864 + } 8865 + } 8866 + break; 8867 + default: 8868 + // T <call-offset> <base encoding> 8869 + { 8870 + const char* t0 = __parse_call_offset(first+1, last); 8871 + if (t0 == first+1) 8872 + break; 8873 + t = __parse_encoding(t0, last); 8874 + if (t != t0) 8875 + { 8876 + if (first[2] == 'v') 8877 + { 8878 + if (__make<__virtual_thunk>(__root_)) 8879 + first = t; 8880 + } 8881 + else 8882 + { 8883 + if (__make<__non_virtual_thunk>(__root_)) 8884 + first = t; 8885 + } 8886 + } 8887 + } 8888 + break; 8889 + } 8890 + break; 8891 + case 'G': 8892 + switch (first[1]) 8893 + { 8894 + case 'V': 8895 + // GV <object name> # Guard variable for one-time initialization 8896 + t = __parse_name(first+2, last); 8897 + if (t != first+2 && __make<__guard_variable>(__root_)) 8898 + first = t; 8899 + break; 8900 + case 'R': 8901 + // extension ::= GR <object name> # reference temporary for object 8902 + t = __parse_name(first+2, last); 8903 + if (t != first+2 && __make<__reference_temporary>(__root_)) 8904 + first = t; 8905 + break; 8906 + } 8907 + break; 8908 + } 8909 + } 8910 + return first; 8911 + } 8912 + 8913 + // <operator-name> 8914 + // ::= aa # && 8915 + // ::= ad # & (unary) 8916 + // ::= an # & 8917 + // ::= aN # &= 8918 + // ::= aS # = 8919 + // ::= at # alignof (a type) 8920 + // ::= az # alignof (an expression) 8921 + // ::= cl # () 8922 + // ::= cm # , 8923 + // ::= co # ~ 8924 + // ::= cv <type> # (cast) 8925 + // ::= da # delete[] 8926 + // ::= de # * (unary) 8927 + // ::= dl # delete 8928 + // ::= dv # / 8929 + // ::= dV # /= 8930 + // ::= eo # ^ 8931 + // ::= eO # ^= 8932 + // ::= eq # == 8933 + // ::= ge # >= 8934 + // ::= gt # > 8935 + // ::= ix # [] 8936 + // ::= le # <= 8937 + // ::= ls # << 8938 + // ::= lS # <<= 8939 + // ::= lt # < 8940 + // ::= mi # - 8941 + // ::= mI # -= 8942 + // ::= ml # * 8943 + // ::= mL # *= 8944 + // ::= mm # -- (postfix in <expression> context) 8945 + // ::= na # new[] 8946 + // ::= ne # != 8947 + // ::= ng # - (unary) 8948 + // ::= nt # ! 8949 + // ::= nw # new 8950 + // ::= oo # || 8951 + // ::= or # | 8952 + // ::= oR # |= 8953 + // ::= pm # ->* 8954 + // ::= pl # + 8955 + // ::= pL # += 8956 + // ::= pp # ++ (postfix in <expression> context) 8957 + // ::= ps # + (unary) 8958 + // ::= pt # -> 8959 + // ::= qu # ? 8960 + // ::= rm # % 8961 + // ::= rM # %= 8962 + // ::= rs # >> 8963 + // ::= rS # >>= 8964 + // ::= st # sizeof (a type) 8965 + // ::= sz # sizeof (an expression) 8966 + // ::= v <digit> <source-name> # vendor extended operator 8967 + 8968 + const char* 8969 + __demangle_tree::__parse_operator_name(const char* first, const char* last, int* type) 8970 + { 8971 + if (last - first >= 2) 8972 + { 8973 + switch (*first) 8974 + { 8975 + case 'a': 8976 + switch (first[1]) 8977 + { 8978 + case 'a': 8979 + // && 8980 + if (type) 8981 + { 8982 + const char* t = __parse_expression(first+2, last); 8983 + if (t != first+2) 8984 + { 8985 + __node* op1 = __root_; 8986 + const char* t2 = __parse_expression(t, last); 8987 + if (t != t2) 8988 + { 8989 + if (__make<__operator_logical_and>(op1, __root_)) 8990 + { 8991 + *type = 2; 8992 + first = t2; 8993 + } 8994 + } 8995 + } 8996 + } 8997 + else 8998 + { 8999 + if (__make<__operator_logical_and>()) 9000 + first += 2; 9001 + } 9002 + break; 9003 + case 'd': 9004 + // & (unary) 9005 + if (type) 9006 + { 9007 + const char* t = __parse_expression(first+2, last); 9008 + if (t != first+2) 9009 + { 9010 + if (__make<__operator_addressof>(__root_)) 9011 + { 9012 + *type = 1; 9013 + first = t; 9014 + } 9015 + } 9016 + } 9017 + else 9018 + { 9019 + if (__make<__operator_addressof>()) 9020 + first += 2; 9021 + } 9022 + break; 9023 + case 'n': 9024 + // & 9025 + if (type) 9026 + { 9027 + const char* t = __parse_expression(first+2, last); 9028 + if (t != first+2) 9029 + { 9030 + __node* op1 = __root_; 9031 + const char* t2 = __parse_expression(t, last); 9032 + if (t != t2) 9033 + { 9034 + if (__make<__operator_bit_and>(op1, __root_)) 9035 + { 9036 + *type = 2; 9037 + first = t2; 9038 + } 9039 + } 9040 + } 9041 + } 9042 + else 9043 + { 9044 + if (__make<__operator_bit_and>()) 9045 + first += 2; 9046 + } 9047 + break; 9048 + case 'N': 9049 + // &= 9050 + if (type) 9051 + { 9052 + const char* t = __parse_expression(first+2, last); 9053 + if (t != first+2) 9054 + { 9055 + __node* op1 = __root_; 9056 + const char* t2 = __parse_expression(t, last); 9057 + if (t != t2) 9058 + { 9059 + if (__make<__operator_and_equal>(op1, __root_)) 9060 + { 9061 + *type = 2; 9062 + first = t2; 9063 + } 9064 + } 9065 + } 9066 + } 9067 + else 9068 + { 9069 + if (__make<__operator_and_equal>()) 9070 + first += 2; 9071 + } 9072 + break; 9073 + case 'S': 9074 + // = 9075 + if (type) 9076 + { 9077 + const char* t = __parse_expression(first+2, last); 9078 + if (t != first+2) 9079 + { 9080 + __node* op1 = __root_; 9081 + const char* t2 = __parse_expression(t, last); 9082 + if (t != t2) 9083 + { 9084 + if (__make<__operator_equal>(op1, __root_)) 9085 + { 9086 + *type = 2; 9087 + first = t2; 9088 + } 9089 + } 9090 + } 9091 + } 9092 + else 9093 + { 9094 + if (__make<__operator_equal>()) 9095 + first += 2; 9096 + } 9097 + break; 9098 + case 't': 9099 + // alignof (a type) 9100 + if (type) 9101 + { 9102 + const char* t = __parse_expression(first+2, last); 9103 + if (t != first+2) 9104 + { 9105 + if (__make<__operator_alignof_type>(__root_)) 9106 + { 9107 + *type = -1; 9108 + first = t; 9109 + } 9110 + } 9111 + } 9112 + else 9113 + { 9114 + if (__make<__operator_alignof_type>()) 9115 + first += 2; 9116 + } 9117 + break; 9118 + case 'z': 9119 + // alignof (an expression) 9120 + if (type) 9121 + { 9122 + const char* t = __parse_expression(first+2, last); 9123 + if (t != first+2) 9124 + { 9125 + if (__make<__operator_alignof_expression>(__root_)) 9126 + { 9127 + *type = -1; 9128 + first = t; 9129 + } 9130 + } 9131 + } 9132 + else 9133 + { 9134 + if (__make<__operator_alignof_expression>()) 9135 + first += 2; 9136 + } 9137 + break; 9138 + } 9139 + break; 9140 + case 'c': 9141 + switch (first[1]) 9142 + { 9143 + case 'l': 9144 + // () 9145 + if (__make<__operator_paren>()) 9146 + { 9147 + first += 2; 9148 + if (type) 9149 + *type = -1; 9150 + } 9151 + break; 9152 + case 'm': 9153 + // , 9154 + if (type) 9155 + { 9156 + const char* t = __parse_expression(first+2, last); 9157 + if (t != first+2) 9158 + { 9159 + __node* op1 = __root_; 9160 + const char* t2 = __parse_expression(t, last); 9161 + if (t != t2) 9162 + { 9163 + if (__make<__operator_comma>(op1, __root_)) 9164 + { 9165 + *type = 2; 9166 + first = t2; 9167 + } 9168 + } 9169 + } 9170 + } 9171 + else 9172 + { 9173 + if (__make<__operator_comma>()) 9174 + first += 2; 9175 + } 9176 + break; 9177 + case 'o': 9178 + // ~ 9179 + if (type) 9180 + { 9181 + const char* t = __parse_expression(first+2, last); 9182 + if (t != first+2) 9183 + { 9184 + if (__make<__operator_tilda>(__root_)) 9185 + { 9186 + *type = 1; 9187 + first = t; 9188 + } 9189 + } 9190 + } 9191 + else 9192 + { 9193 + if (__make<__operator_tilda>()) 9194 + first += 2; 9195 + } 9196 + break; 9197 + case 'v': 9198 + // cast <type> 9199 + { 9200 + const char* t = __parse_type(first+2, last, false, true); 9201 + if (t != first+2) 9202 + { 9203 + __node* cast_type = __root_; 9204 + if (type) 9205 + { 9206 + const char* t2 = __parse_expression(t, last); 9207 + if (t2 != t) 9208 + { 9209 + if (__make<__operator_cast>(cast_type, __root_)) 9210 + { 9211 + *type = -1; 9212 + first = t2; 9213 + } 9214 + } 9215 + } 9216 + else 9217 + { 9218 + if (__make<__operator_cast>(cast_type)) 9219 + first = t; 9220 + } 9221 + } 9222 + } 9223 + break; 9224 + } 9225 + break; 9226 + case 'd': 9227 + switch (first[1]) 9228 + { 9229 + case 'a': 9230 + // delete[] 9231 + if (__make<__operator_delete_array>()) 9232 + { 9233 + first += 2; 9234 + if (type) 9235 + *type = -1; 9236 + } 9237 + break; 9238 + case 'e': 9239 + // * (unary) 9240 + if (type) 9241 + { 9242 + const char* t = __parse_expression(first+2, last); 9243 + if (t != first+2) 9244 + { 9245 + if (__make<__operator_dereference>(__root_)) 9246 + { 9247 + *type = 1; 9248 + first = t; 9249 + } 9250 + } 9251 + } 9252 + else 9253 + { 9254 + if (__make<__operator_dereference>()) 9255 + first += 2; 9256 + } 9257 + break; 9258 + case 'l': 9259 + // delete 9260 + if (__make<__operator_delete>()) 9261 + { 9262 + first += 2; 9263 + if (type) 9264 + *type = -1; 9265 + } 9266 + break; 9267 + case 'v': 9268 + // / 9269 + if (type) 9270 + { 9271 + const char* t = __parse_expression(first+2, last); 9272 + if (t != first+2) 9273 + { 9274 + __node* op1 = __root_; 9275 + const char* t2 = __parse_expression(t, last); 9276 + if (t != t2) 9277 + { 9278 + if (__make<__operator_divide>(op1, __root_)) 9279 + { 9280 + *type = 2; 9281 + first = t2; 9282 + } 9283 + } 9284 + } 9285 + } 9286 + else 9287 + { 9288 + if (__make<__operator_divide>()) 9289 + first += 2; 9290 + } 9291 + break; 9292 + case 'V': 9293 + // /= 9294 + if (type) 9295 + { 9296 + const char* t = __parse_expression(first+2, last); 9297 + if (t != first+2) 9298 + { 9299 + __node* op1 = __root_; 9300 + const char* t2 = __parse_expression(t, last); 9301 + if (t != t2) 9302 + { 9303 + if (__make<__operator_divide_equal>(op1, __root_)) 9304 + { 9305 + *type = 2; 9306 + first = t2; 9307 + } 9308 + } 9309 + } 9310 + } 9311 + else 9312 + { 9313 + if (__make<__operator_divide_equal>()) 9314 + first += 2; 9315 + } 9316 + break; 9317 + } 9318 + break; 9319 + case 'e': 9320 + switch (first[1]) 9321 + { 9322 + case 'o': 9323 + // ^ 9324 + if (type) 9325 + { 9326 + const char* t = __parse_expression(first+2, last); 9327 + if (t != first+2) 9328 + { 9329 + __node* op1 = __root_; 9330 + const char* t2 = __parse_expression(t, last); 9331 + if (t != t2) 9332 + { 9333 + if (__make<__operator_xor>(op1, __root_)) 9334 + { 9335 + *type = 2; 9336 + first = t2; 9337 + } 9338 + } 9339 + } 9340 + } 9341 + else 9342 + { 9343 + if (__make<__operator_xor>()) 9344 + first += 2; 9345 + } 9346 + break; 9347 + case 'O': 9348 + // ^= 9349 + if (type) 9350 + { 9351 + const char* t = __parse_expression(first+2, last); 9352 + if (t != first+2) 9353 + { 9354 + __node* op1 = __root_; 9355 + const char* t2 = __parse_expression(t, last); 9356 + if (t != t2) 9357 + { 9358 + if (__make<__operator_xor_equal>(op1, __root_)) 9359 + { 9360 + *type = 2; 9361 + first = t2; 9362 + } 9363 + } 9364 + } 9365 + } 9366 + else 9367 + { 9368 + if (__make<__operator_xor_equal>()) 9369 + first += 2; 9370 + } 9371 + break; 9372 + case 'q': 9373 + // == 9374 + if (type) 9375 + { 9376 + const char* t = __parse_expression(first+2, last); 9377 + if (t != first+2) 9378 + { 9379 + __node* op1 = __root_; 9380 + const char* t2 = __parse_expression(t, last); 9381 + if (t != t2) 9382 + { 9383 + if (__make<__operator_equality>(op1, __root_)) 9384 + { 9385 + *type = 2; 9386 + first = t2; 9387 + } 9388 + } 9389 + } 9390 + } 9391 + else 9392 + { 9393 + if (__make<__operator_equality>()) 9394 + first += 2; 9395 + } 9396 + break; 9397 + } 9398 + break; 9399 + case 'g': 9400 + switch (first[1]) 9401 + { 9402 + case 'e': 9403 + // >= 9404 + if (type) 9405 + { 9406 + const char* t = __parse_expression(first+2, last); 9407 + if (t != first+2) 9408 + { 9409 + __node* op1 = __root_; 9410 + const char* t2 = __parse_expression(t, last); 9411 + if (t != t2) 9412 + { 9413 + if (__make<__operator_greater_equal>(op1, __root_)) 9414 + { 9415 + *type = 2; 9416 + first = t2; 9417 + } 9418 + } 9419 + } 9420 + } 9421 + else 9422 + { 9423 + if (__make<__operator_greater_equal>()) 9424 + first += 2; 9425 + } 9426 + break; 9427 + case 't': 9428 + // > 9429 + if (type) 9430 + { 9431 + const char* t = __parse_expression(first+2, last); 9432 + if (t != first+2) 9433 + { 9434 + __node* op1 = __root_; 9435 + const char* t2 = __parse_expression(t, last); 9436 + if (t != t2) 9437 + { 9438 + if (__make<__operator_greater>(op1, __root_)) 9439 + { 9440 + *type = 2; 9441 + first = t2; 9442 + } 9443 + } 9444 + } 9445 + } 9446 + else 9447 + { 9448 + if (__make<__operator_greater>()) 9449 + first += 2; 9450 + } 9451 + break; 9452 + } 9453 + break; 9454 + case 'i': 9455 + // [] 9456 + if (first[1] == 'x' && __make<__operator_brackets>()) 9457 + { 9458 + first += 2; 9459 + if (type) 9460 + *type = -1; 9461 + } 9462 + break; 9463 + case 'l': 9464 + switch (first[1]) 9465 + { 9466 + case 'e': 9467 + // <= 9468 + if (type) 9469 + { 9470 + const char* t = __parse_expression(first+2, last); 9471 + if (t != first+2) 9472 + { 9473 + __node* op1 = __root_; 9474 + const char* t2 = __parse_expression(t, last); 9475 + if (t != t2) 9476 + { 9477 + if (__make<__operator_less_equal>(op1, __root_)) 9478 + { 9479 + *type = 2; 9480 + first = t2; 9481 + } 9482 + } 9483 + } 9484 + } 9485 + else 9486 + { 9487 + if (__make<__operator_less_equal>()) 9488 + first += 2; 9489 + } 9490 + break; 9491 + case 's': 9492 + // << 9493 + if (type) 9494 + { 9495 + const char* t = __parse_expression(first+2, last); 9496 + if (t != first+2) 9497 + { 9498 + __node* op1 = __root_; 9499 + const char* t2 = __parse_expression(t, last); 9500 + if (t != t2) 9501 + { 9502 + if (__make<__operator_left_shift>(op1, __root_)) 9503 + { 9504 + *type = 2; 9505 + first = t2; 9506 + } 9507 + } 9508 + } 9509 + } 9510 + else 9511 + { 9512 + if (__make<__operator_left_shift>()) 9513 + first += 2; 9514 + } 9515 + break; 9516 + case 'S': 9517 + // <<= 9518 + if (type) 9519 + { 9520 + const char* t = __parse_expression(first+2, last); 9521 + if (t != first+2) 9522 + { 9523 + __node* op1 = __root_; 9524 + const char* t2 = __parse_expression(t, last); 9525 + if (t != t2) 9526 + { 9527 + if (__make<__operator_left_shift_equal>(op1, __root_)) 9528 + { 9529 + *type = 2; 9530 + first = t2; 9531 + } 9532 + } 9533 + } 9534 + } 9535 + else 9536 + { 9537 + if (__make<__operator_left_shift_equal>()) 9538 + first += 2; 9539 + } 9540 + break; 9541 + case 't': 9542 + // < 9543 + if (type) 9544 + { 9545 + const char* t = __parse_expression(first+2, last); 9546 + if (t != first+2) 9547 + { 9548 + __node* op1 = __root_; 9549 + const char* t2 = __parse_expression(t, last); 9550 + if (t != t2) 9551 + { 9552 + if (__make<__operator_less>(op1, __root_)) 9553 + { 9554 + *type = 2; 9555 + first = t2; 9556 + } 9557 + } 9558 + } 9559 + } 9560 + else 9561 + { 9562 + if (__make<__operator_less>()) 9563 + first += 2; 9564 + } 9565 + break; 9566 + } 9567 + break; 9568 + case 'm': 9569 + switch (first[1]) 9570 + { 9571 + case 'i': 9572 + // - 9573 + if (type) 9574 + { 9575 + const char* t = __parse_expression(first+2, last); 9576 + if (t != first+2) 9577 + { 9578 + __node* op1 = __root_; 9579 + const char* t2 = __parse_expression(t, last); 9580 + if (t != t2) 9581 + { 9582 + if (__make<__operator_minus>(op1, __root_)) 9583 + { 9584 + *type = 2; 9585 + first = t2; 9586 + } 9587 + } 9588 + } 9589 + } 9590 + else 9591 + { 9592 + if (__make<__operator_minus>()) 9593 + first += 2; 9594 + } 9595 + break; 9596 + case 'I': 9597 + // -= 9598 + if (type) 9599 + { 9600 + const char* t = __parse_expression(first+2, last); 9601 + if (t != first+2) 9602 + { 9603 + __node* op1 = __root_; 9604 + const char* t2 = __parse_expression(t, last); 9605 + if (t != t2) 9606 + { 9607 + if (__make<__operator_minus_equal>(op1, __root_)) 9608 + { 9609 + *type = 2; 9610 + first = t2; 9611 + } 9612 + } 9613 + } 9614 + } 9615 + else 9616 + { 9617 + if (__make<__operator_minus_equal>()) 9618 + first += 2; 9619 + } 9620 + break; 9621 + case 'l': 9622 + // * 9623 + if (type) 9624 + { 9625 + const char* t = __parse_expression(first+2, last); 9626 + if (t != first+2) 9627 + { 9628 + __node* op1 = __root_; 9629 + const char* t2 = __parse_expression(t, last); 9630 + if (t != t2) 9631 + { 9632 + if (__make<__operator_times>(op1, __root_)) 9633 + { 9634 + *type = 2; 9635 + first = t2; 9636 + } 9637 + } 9638 + } 9639 + } 9640 + else 9641 + { 9642 + if (__make<__operator_times>()) 9643 + first += 2; 9644 + } 9645 + break; 9646 + case 'L': 9647 + // *= 9648 + if (type) 9649 + { 9650 + const char* t = __parse_expression(first+2, last); 9651 + if (t != first+2) 9652 + { 9653 + __node* op1 = __root_; 9654 + const char* t2 = __parse_expression(t, last); 9655 + if (t != t2) 9656 + { 9657 + if (__make<__operator_times_equal>(op1, __root_)) 9658 + { 9659 + *type = 2; 9660 + first = t2; 9661 + } 9662 + } 9663 + } 9664 + } 9665 + else 9666 + { 9667 + if (__make<__operator_times_equal>()) 9668 + first += 2; 9669 + } 9670 + break; 9671 + case 'm': 9672 + // -- (postfix in <expression> context) 9673 + if (type) 9674 + { 9675 + const char* t = __parse_expression(first+2, last); 9676 + if (t != first+2) 9677 + { 9678 + if (__make<__operator_decrement>(false, __root_)) 9679 + { 9680 + *type = 1; 9681 + first = t; 9682 + } 9683 + } 9684 + } 9685 + else 9686 + { 9687 + if (__make<__operator_decrement>()) 9688 + first += 2; 9689 + } 9690 + break; 9691 + } 9692 + break; 9693 + case 'n': 9694 + switch (first[1]) 9695 + { 9696 + case 'a': 9697 + // new[] 9698 + if (__make<__operator_new_array>()) 9699 + { 9700 + first += 2; 9701 + if (type) 9702 + *type = -1; 9703 + } 9704 + break; 9705 + case 'e': 9706 + // != 9707 + if (type) 9708 + { 9709 + const char* t = __parse_expression(first+2, last); 9710 + if (t != first+2) 9711 + { 9712 + __node* op1 = __root_; 9713 + const char* t2 = __parse_expression(t, last); 9714 + if (t != t2) 9715 + { 9716 + if (__make<__operator_not_equal>(op1, __root_)) 9717 + { 9718 + *type = 2; 9719 + first = t2; 9720 + } 9721 + } 9722 + } 9723 + } 9724 + else 9725 + { 9726 + if (__make<__operator_not_equal>()) 9727 + first += 2; 9728 + } 9729 + break; 9730 + case 'g': 9731 + // - (unary) 9732 + if (type) 9733 + { 9734 + const char* t = __parse_expression(first+2, last); 9735 + if (t != first+2) 9736 + { 9737 + if (__make<__operator_negate>(__root_)) 9738 + { 9739 + *type = 1; 9740 + first = t; 9741 + } 9742 + } 9743 + } 9744 + else 9745 + { 9746 + if (__make<__operator_negate>()) 9747 + first += 2; 9748 + } 9749 + break; 9750 + case 't': 9751 + // ! 9752 + if (type) 9753 + { 9754 + const char* t = __parse_expression(first+2, last); 9755 + if (t != first+2) 9756 + { 9757 + if (__make<__operator_logical_not>(__root_)) 9758 + { 9759 + *type = 1; 9760 + first = t; 9761 + } 9762 + } 9763 + } 9764 + else 9765 + { 9766 + if (__make<__operator_logical_not>()) 9767 + first += 2; 9768 + } 9769 + break; 9770 + case 'w': 9771 + // new 9772 + if (__make<__operator_new>()) 9773 + { 9774 + first += 2; 9775 + if (type) 9776 + *type = -1; 9777 + } 9778 + break; 9779 + } 9780 + break; 9781 + case 'o': 9782 + switch (first[1]) 9783 + { 9784 + case 'o': 9785 + // || 9786 + if (type) 9787 + { 9788 + const char* t = __parse_expression(first+2, last); 9789 + if (t != first+2) 9790 + { 9791 + __node* op1 = __root_; 9792 + const char* t2 = __parse_expression(t, last); 9793 + if (t != t2) 9794 + { 9795 + if (__make<__operator_logical_or>(op1, __root_)) 9796 + { 9797 + *type = 2; 9798 + first = t2; 9799 + } 9800 + } 9801 + } 9802 + } 9803 + else 9804 + { 9805 + if (__make<__operator_logical_or>()) 9806 + first += 2; 9807 + } 9808 + break; 9809 + case 'r': 9810 + // | 9811 + if (type) 9812 + { 9813 + const char* t = __parse_expression(first+2, last); 9814 + if (t != first+2) 9815 + { 9816 + __node* op1 = __root_; 9817 + const char* t2 = __parse_expression(t, last); 9818 + if (t != t2) 9819 + { 9820 + if (__make<__operator_bit_or>(op1, __root_)) 9821 + { 9822 + *type = 2; 9823 + first = t2; 9824 + } 9825 + } 9826 + } 9827 + } 9828 + else 9829 + { 9830 + if (__make<__operator_bit_or>()) 9831 + first += 2; 9832 + } 9833 + break; 9834 + case 'R': 9835 + // |= 9836 + if (type) 9837 + { 9838 + const char* t = __parse_expression(first+2, last); 9839 + if (t != first+2) 9840 + { 9841 + __node* op1 = __root_; 9842 + const char* t2 = __parse_expression(t, last); 9843 + if (t != t2) 9844 + { 9845 + if (__make<__operator_or_equal>(op1, __root_)) 9846 + { 9847 + *type = 2; 9848 + first = t2; 9849 + } 9850 + } 9851 + } 9852 + } 9853 + else 9854 + { 9855 + if (__make<__operator_or_equal>()) 9856 + first += 2; 9857 + } 9858 + break; 9859 + } 9860 + break; 9861 + case 'p': 9862 + switch (first[1]) 9863 + { 9864 + case 'm': 9865 + // ->* 9866 + if (type) 9867 + { 9868 + const char* t = __parse_expression(first+2, last); 9869 + if (t != first+2) 9870 + { 9871 + __node* op1 = __root_; 9872 + const char* t2 = __parse_expression(t, last); 9873 + if (t != t2) 9874 + { 9875 + if (__make<__operator_pointer_to_member>(op1, __root_)) 9876 + { 9877 + *type = 2; 9878 + first = t2; 9879 + } 9880 + } 9881 + } 9882 + } 9883 + else 9884 + { 9885 + if (__make<__operator_pointer_to_member>()) 9886 + first += 2; 9887 + } 9888 + break; 9889 + case 'l': 9890 + // + 9891 + if (type) 9892 + { 9893 + const char* t = __parse_expression(first+2, last); 9894 + if (t != first+2) 9895 + { 9896 + __node* op1 = __root_; 9897 + const char* t2 = __parse_expression(t, last); 9898 + if (t != t2) 9899 + { 9900 + if (__make<__operator_plus>(op1, __root_)) 9901 + { 9902 + *type = 2; 9903 + first = t2; 9904 + } 9905 + } 9906 + } 9907 + } 9908 + else 9909 + { 9910 + if (__make<__operator_plus>()) 9911 + first += 2; 9912 + } 9913 + break; 9914 + case 'L': 9915 + // += 9916 + if (type) 9917 + { 9918 + const char* t = __parse_expression(first+2, last); 9919 + if (t != first+2) 9920 + { 9921 + __node* op1 = __root_; 9922 + const char* t2 = __parse_expression(t, last); 9923 + if (t != t2) 9924 + { 9925 + if (__make<__operator_plus_equal>(op1, __root_)) 9926 + { 9927 + *type = 2; 9928 + first = t2; 9929 + } 9930 + } 9931 + } 9932 + } 9933 + else 9934 + { 9935 + if (__make<__operator_plus_equal>()) 9936 + first += 2; 9937 + } 9938 + break; 9939 + case 'p': 9940 + // ++ (postfix in <expression> context) 9941 + if (type) 9942 + { 9943 + const char* t = __parse_expression(first+2, last); 9944 + if (t != first+2) 9945 + { 9946 + if (__make<__operator_increment>(false, __root_)) 9947 + { 9948 + *type = 1; 9949 + first = t; 9950 + } 9951 + } 9952 + } 9953 + else 9954 + { 9955 + if (__make<__operator_increment>()) 9956 + first += 2; 9957 + } 9958 + break; 9959 + case 's': 9960 + // + (unary) 9961 + if (type) 9962 + { 9963 + const char* t = __parse_expression(first+2, last); 9964 + if (t != first+2) 9965 + { 9966 + if (__make<__operator_unary_plus>(__root_)) 9967 + { 9968 + *type = 1; 9969 + first = t; 9970 + } 9971 + } 9972 + } 9973 + else 9974 + { 9975 + if (__make<__operator_unary_plus>()) 9976 + first += 2; 9977 + } 9978 + break; 9979 + case 't': 9980 + // -> 9981 + if (type) 9982 + { 9983 + const char* t = __parse_expression(first+2, last); 9984 + if (t != first+2) 9985 + { 9986 + __node* op1 = __root_; 9987 + const char* t2 = __parse_expression(t, last); 9988 + if (t != t2) 9989 + { 9990 + if (__make<__operator_arrow>(op1, __root_)) 9991 + { 9992 + *type = 2; 9993 + first = t2; 9994 + } 9995 + } 9996 + } 9997 + } 9998 + else 9999 + { 10000 + if (__make<__operator_arrow>()) 10001 + first += 2; 10002 + } 10003 + break; 10004 + } 10005 + break; 10006 + case 'q': 10007 + // ? 10008 + if (first[1] == 'u') 10009 + { 10010 + if (type) 10011 + { 10012 + const char* t = __parse_expression(first+2, last); 10013 + if (t != first+2) 10014 + { 10015 + __node* op1 = __root_; 10016 + const char* t2 = __parse_expression(t, last); 10017 + if (t != t2) 10018 + { 10019 + __node* op2 = __root_; 10020 + const char* t3 = __parse_expression(t2, last); 10021 + if (t3 != t2) 10022 + { 10023 + if (__make<__operator_conditional>(op1, op2, __root_)) 10024 + { 10025 + *type = 3; 10026 + first = t3; 10027 + } 10028 + } 10029 + } 10030 + } 10031 + } 10032 + else 10033 + { 10034 + if (__make<__operator_conditional>()) 10035 + first += 2; 10036 + } 10037 + } 10038 + break; 10039 + case 'r': 10040 + switch (first[1]) 10041 + { 10042 + case 'm': 10043 + // % 10044 + if (type) 10045 + { 10046 + const char* t = __parse_expression(first+2, last); 10047 + if (t != first+2) 10048 + { 10049 + __node* op1 = __root_; 10050 + const char* t2 = __parse_expression(t, last); 10051 + if (t != t2) 10052 + { 10053 + if (__make<__operator_mod>(op1, __root_)) 10054 + { 10055 + *type = 2; 10056 + first = t2; 10057 + } 10058 + } 10059 + } 10060 + } 10061 + else 10062 + { 10063 + if (__make<__operator_mod>()) 10064 + first += 2; 10065 + } 10066 + break; 10067 + case 'M': 10068 + // %= 10069 + if (type) 10070 + { 10071 + const char* t = __parse_expression(first+2, last); 10072 + if (t != first+2) 10073 + { 10074 + __node* op1 = __root_; 10075 + const char* t2 = __parse_expression(t, last); 10076 + if (t != t2) 10077 + { 10078 + if (__make<__operator_mod_equal>(op1, __root_)) 10079 + { 10080 + *type = 2; 10081 + first = t2; 10082 + } 10083 + } 10084 + } 10085 + } 10086 + else 10087 + { 10088 + if (__make<__operator_mod_equal>()) 10089 + first += 2; 10090 + } 10091 + break; 10092 + case 's': 10093 + // >> 10094 + if (type) 10095 + { 10096 + const char* t = __parse_expression(first+2, last); 10097 + if (t != first+2) 10098 + { 10099 + __node* op1 = __root_; 10100 + const char* t2 = __parse_expression(t, last); 10101 + if (t != t2) 10102 + { 10103 + if (__make<__operator_right_shift>(op1, __root_)) 10104 + { 10105 + *type = 2; 10106 + first = t2; 10107 + } 10108 + } 10109 + } 10110 + } 10111 + else 10112 + { 10113 + if (__make<__operator_right_shift>()) 10114 + first += 2; 10115 + } 10116 + break; 10117 + case 'S': 10118 + // >>= 10119 + if (type) 10120 + { 10121 + const char* t = __parse_expression(first+2, last); 10122 + if (t != first+2) 10123 + { 10124 + __node* op1 = __root_; 10125 + const char* t2 = __parse_expression(t, last); 10126 + if (t != t2) 10127 + { 10128 + if (__make<__operator_right_shift_equal>(op1, __root_)) 10129 + { 10130 + *type = 2; 10131 + first = t2; 10132 + } 10133 + } 10134 + } 10135 + } 10136 + else 10137 + { 10138 + if (__make<__operator_right_shift_equal>()) 10139 + first += 2; 10140 + } 10141 + break; 10142 + } 10143 + break; 10144 + case 's': 10145 + switch (first[1]) 10146 + { 10147 + case 't': 10148 + // sizeof (a type) 10149 + if (type) 10150 + { 10151 + const char* t = __parse_expression(first+2, last); 10152 + if (t != first+2) 10153 + { 10154 + if (__make<__operator_sizeof_type>(__root_)) 10155 + { 10156 + *type = -1; 10157 + first = t; 10158 + } 10159 + } 10160 + } 10161 + else 10162 + { 10163 + if (__make<__operator_sizeof_type>()) 10164 + first += 2; 10165 + } 10166 + break; 10167 + case 'z': 10168 + // sizeof (an expression) 10169 + if (type) 10170 + { 10171 + const char* t = __parse_expression(first+2, last); 10172 + if (t != first+2) 10173 + { 10174 + if (__make<__operator_sizeof_expression>(__root_)) 10175 + { 10176 + *type = -1; 10177 + first = t; 10178 + } 10179 + } 10180 + } 10181 + else 10182 + { 10183 + if (__make<__operator_sizeof_expression>()) 10184 + first += 2; 10185 + } 10186 + break; 10187 + } 10188 + break; 10189 + } 10190 + } 10191 + return first; 10192 + } 10193 + 10194 + // <source-name> ::= <positive length number> <identifier> 10195 + 10196 + const char* 10197 + __demangle_tree::__parse_source_name(const char* first, const char* last) 10198 + { 10199 + if (first != last) 10200 + { 10201 + char c = *first; 10202 + if ('1' <= c && c <= '9' && first+1 != last) 10203 + { 10204 + const char* t = first+1; 10205 + size_t n = static_cast<size_t>(c - '0'); 10206 + for (c = *t; '0' <= c && c <= '9'; c = *t) 10207 + { 10208 + n = n * 10 + static_cast<size_t>(c - '0'); 10209 + if (++t == last) 10210 + return first; 10211 + } 10212 + if (static_cast<size_t>(last - t) >= n && __make<__source_name>(t, n)) 10213 + first = t + n; 10214 + } 10215 + } 10216 + return first; 10217 + } 10218 + 10219 + // <unqualified-name> ::= <operator-name> 10220 + // ::= <ctor-dtor-name> 10221 + // ::= <source-name> 10222 + // ::= <unnamed-type-name> 10223 + 10224 + const char* 10225 + __demangle_tree::__parse_unqualified_name(const char* first, const char* last) 10226 + { 10227 + const char* t = __parse_source_name(first, last); 10228 + if (t == first) 10229 + { 10230 + t = __parse_ctor_dtor_name(first, last); 10231 + if (t == first) 10232 + { 10233 + t = __parse_operator_name(first, last); 10234 + if (t == first) 10235 + first = __parse_unnamed_type_name(first, last); 10236 + else 10237 + first = t; 10238 + } 10239 + else 10240 + first = t; 10241 + } 10242 + else 10243 + first = t; 10244 + return first; 10245 + } 10246 + 10247 + // <unscoped-name> ::= <unqualified-name> 10248 + // ::= St <unqualified-name> # ::std:: 10249 + // extension ::= StL<unqualified-name> 10250 + 10251 + const char* 10252 + __demangle_tree::__parse_unscoped_name(const char* first, const char* last) 10253 + { 10254 + if (last - first >= 2) 10255 + { 10256 + const char* t0 = first; 10257 + if (first[0] == 'S' && first[1] == 't') 10258 + { 10259 + t0 += 2; 10260 + if (t0 != last && *t0 == 'L') 10261 + ++t0; 10262 + } 10263 + const char* t1 = __parse_unqualified_name(t0, last); 10264 + if (t1 != t0) 10265 + { 10266 + if (t0 != first) 10267 + { 10268 + __node* name = __root_; 10269 + if (__make<__std_qualified_name>()) 10270 + { 10271 + if (__make<__nested_delimeter>(__root_, name)) 10272 + first = t1; 10273 + } 10274 + } 10275 + else 10276 + first = t1; 10277 + } 10278 + } 10279 + return first; 10280 + } 10281 + 10282 + // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E 10283 + // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E 10284 + // 10285 + // <prefix> ::= <prefix> <unqualified-name> 10286 + // ::= <template-prefix> <template-args> 10287 + // ::= <template-param> 10288 + // ::= <decltype> 10289 + // ::= # empty 10290 + // ::= <substitution> 10291 + // ::= <prefix> <data-member-prefix> 10292 + // extension ::= L 10293 + // 10294 + // <template-prefix> ::= <prefix> <template unqualified-name> 10295 + // ::= <template-param> 10296 + // ::= <substitution> 10297 + 10298 + const char* 10299 + __demangle_tree::__parse_nested_name(const char* first, const char* last) 10300 + { 10301 + if (first != last && *first == 'N') 10302 + { 10303 + unsigned cv = 0; 10304 + const char* t0 = __parse_cv_qualifiers(first+1, last, cv, true); 10305 + __node* prev = NULL; 10306 + if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't') 10307 + { 10308 + t0 += 2; 10309 + if (!__make<__std_qualified_name>()) 10310 + return first; 10311 + prev = __root_; 10312 + } 10313 + while (t0 != last) 10314 + { 10315 + bool can_sub = true; 10316 + bool make_nested = true; 10317 + const char* t1 = NULL; 10318 + switch (*t0) 10319 + { 10320 + case '1': 10321 + case '2': 10322 + case '3': 10323 + case '4': 10324 + case '5': 10325 + case '6': 10326 + case '7': 10327 + case '8': 10328 + case '9': 10329 + t1 = __parse_source_name(t0, last); 10330 + if (t1 == t0 || t1 == last) 10331 + return first; 10332 + if (*t1 == 'M') 10333 + { 10334 + // This is a data-member-prefix 10335 + ++t1; 10336 + } 10337 + else if (*t1 == 'I') 10338 + { 10339 + // has following <template-args> 10340 + if (prev) 10341 + { 10342 + if (!__make<__nested_delimeter>(prev, __root_)) 10343 + return first; 10344 + make_nested = false; 10345 + } 10346 + if (__sub_end_ == __sub_cap_) 10347 + { 10348 + __status_ = memory_alloc_failure; 10349 + return first; 10350 + } 10351 + else 10352 + *__sub_end_++ = __root_; 10353 + const char* t2 = __parse_template_args(t1, last); 10354 + if (t2 == t1) 10355 + return first; 10356 + t1 = t2; 10357 + } 10358 + break; 10359 + case 'D': 10360 + if (t0+1 != last && (t0[1] == 't' || t0[1] == 'T')) 10361 + { 10362 + t1 = __parse_decltype(t0, last); 10363 + break; 10364 + } 10365 + // check for Dt, DT here, else drop through 10366 + case 'C': 10367 + t1 = __parse_ctor_dtor_name(t0, last); 10368 + if (t1 == t0 || t1 == last) 10369 + return first; 10370 + if (*t1 == 'I') 10371 + { 10372 + // has following <template-args> 10373 + if (prev) 10374 + { 10375 + if (!__make<__nested_delimeter>(prev, __root_)) 10376 + return first; 10377 + make_nested = false; 10378 + } 10379 + if (__sub_end_ == __sub_cap_) 10380 + { 10381 + __status_ = memory_alloc_failure; 10382 + return first; 10383 + } 10384 + else 10385 + *__sub_end_++ = __root_; 10386 + const char* t2 = __parse_template_args(t1, last); 10387 + if (t2 == t1) 10388 + return first; 10389 + t1 = t2; 10390 + } 10391 + break; 10392 + case 'U': 10393 + t1 = __parse_unnamed_type_name(t0, last); 10394 + if (t1 == t0 || t1 == last) 10395 + return first; 10396 + break; 10397 + case 'T': 10398 + t1 = __parse_template_param(t0, last); 10399 + if (t1 == t0 || t1 == last) 10400 + return first; 10401 + if (*t1 == 'I') 10402 + { 10403 + // has following <template-args> 10404 + if (prev) 10405 + { 10406 + if (!__make<__nested_delimeter>(prev, __root_)) 10407 + return first; 10408 + make_nested = false; 10409 + } 10410 + if (__sub_end_ == __sub_cap_) 10411 + { 10412 + __status_ = memory_alloc_failure; 10413 + return first; 10414 + } 10415 + else 10416 + *__sub_end_++ = __root_; 10417 + const char* t2 = __parse_template_args(t1, last); 10418 + if (t2 == t1) 10419 + return first; 10420 + t1 = t2; 10421 + } 10422 + break; 10423 + case 'S': 10424 + t1 = __parse_substitution(t0, last); 10425 + if (t1 == t0 || t1 == last) 10426 + return first; 10427 + if (*t1 == 'I') 10428 + { 10429 + const char* t2 = __parse_template_args(t1, last); 10430 + if (t2 == t1) 10431 + return first; 10432 + t1 = t2; 10433 + } 10434 + else 10435 + can_sub = false; 10436 + break; 10437 + case 'L': 10438 + // extension: ignore L here 10439 + ++t0; 10440 + continue; 10441 + default: 10442 + t1 = __parse_operator_name(t0, last); 10443 + if (t1 == t0 || t1 == last) 10444 + return first; 10445 + if (*t1 == 'I') 10446 + { 10447 + // has following <template-args> 10448 + if (prev) 10449 + { 10450 + if (!__make<__nested_delimeter>(prev, __root_)) 10451 + return first; 10452 + make_nested = false; 10453 + } 10454 + if (__sub_end_ == __sub_cap_) 10455 + { 10456 + __status_ = memory_alloc_failure; 10457 + return first; 10458 + } 10459 + else 10460 + *__sub_end_++ = __root_; 10461 + const char* t2 = __parse_template_args(t1, last); 10462 + if (t2 == t1) 10463 + return first; 10464 + t1 = t2; 10465 + } 10466 + break; 10467 + } 10468 + if (t1 == t0 || t1 == last) 10469 + return first; 10470 + if (prev && make_nested) 10471 + { 10472 + if (!__make<__nested_delimeter>(prev, __root_)) 10473 + return first; 10474 + can_sub = true; 10475 + } 10476 + if (can_sub && *t1 != 'E') 10477 + { 10478 + if (__sub_end_ == __sub_cap_) 10479 + { 10480 + __status_ = memory_alloc_failure; 10481 + return first; 10482 + } 10483 + else 10484 + *__sub_end_++ = __root_; 10485 + } 10486 + if (*t1 == 'E') 10487 + { 10488 + if (cv != 0) 10489 + { 10490 + if (!__make<__cv_qualifiers>(cv, __root_)) 10491 + return first; 10492 + } 10493 + first = t1+1; 10494 + break; 10495 + } 10496 + prev = __root_; 10497 + t0 = t1; 10498 + } 10499 + } 10500 + return first; 10501 + } 10502 + 10503 + // <template-arg> ::= <type> # type or template 10504 + // ::= X <expression> E # expression 10505 + // ::= <expr-primary> # simple expressions 10506 + // ::= J <template-arg>* E # argument pack 10507 + // ::= LZ <encoding> E # extension 10508 + 10509 + const char* 10510 + __demangle_tree::__parse_template_arg(const char* first, const char* last) 10511 + { 10512 + if (first != last) 10513 + { 10514 + const char* t; 10515 + switch (*first) 10516 + { 10517 + case 'X': 10518 + t = __parse_expression(first+1, last); 10519 + if (t != first+1) 10520 + { 10521 + if (t != last && *t == 'E') 10522 + first = t+1; 10523 + } 10524 + break; 10525 + case 'J': 10526 + t = first+1; 10527 + if (t == last) 10528 + return first; 10529 + if (*t == 'E') 10530 + { 10531 + if (__make<__list>((__node*)0)) 10532 + first = t+1; 10533 + } 10534 + else 10535 + { 10536 + __node* list = NULL; 10537 + __node* prev = NULL; 10538 + do 10539 + { 10540 + const char* t2 = __parse_template_arg(t, last); 10541 + if (t2 == t || !__make<__list>(__root_)) 10542 + return first; 10543 + if (list == 0) 10544 + list = __root_; 10545 + if (prev) 10546 + { 10547 + prev->__right_ = __root_; 10548 + __root_->__size_ = prev->__size_ + 1; 10549 + } 10550 + prev = __root_; 10551 + t = t2; 10552 + } while (t != last && *t != 'E'); 10553 + first = t+1; 10554 + __root_ = list; 10555 + } 10556 + break; 10557 + case 'L': 10558 + // <expr-primary> or LZ <encoding> E 10559 + if (first+1 != last && first[1] == 'Z') 10560 + { 10561 + t = __parse_encoding(first+2, last); 10562 + if (t != first+2 && t != last && *t == 'E') 10563 + first = t+1; 10564 + } 10565 + else 10566 + first = __parse_expr_primary(first, last); 10567 + break; 10568 + default: 10569 + // <type> 10570 + first = __parse_type(first, last); 10571 + break; 10572 + } 10573 + } 10574 + return first; 10575 + } 10576 + 10577 + // <template-args> ::= I <template-arg>* E 10578 + // extension, the abi says <template-arg>+ 10579 + 10580 + const char* 10581 + __demangle_tree::__parse_template_args(const char* first, const char* last) 10582 + { 10583 + if (last - first >= 2 && *first == 'I') 10584 + { 10585 + __node* args = NULL; 10586 + __node* prev = NULL; 10587 + __node* name = __root_; 10588 + if (__tag_templates_) 10589 + __t_end_ = __t_begin_; 10590 + const char* t = first+1; 10591 + while (*t != 'E') 10592 + { 10593 + bool prev_tag_templates = __tag_templates_; 10594 + __node** prev_t_begin = __t_begin_; 10595 + __node** prev_t_end = __t_end_; 10596 + if (__tag_templates_) 10597 + __t_begin_ = __t_end_; 10598 + const char* t2 = __parse_template_arg(t, last); 10599 + if (prev_tag_templates) 10600 + { 10601 + __tag_templates_ = prev_tag_templates; 10602 + __t_begin_ = prev_t_begin; 10603 + __t_end_ = prev_t_end; 10604 + } 10605 + if (t2 == t || t2 == last) 10606 + break; 10607 + if (!__make<__list>(__root_)) 10608 + return first; 10609 + if (args == 0) 10610 + args = __root_; 10611 + if (prev) 10612 + { 10613 + prev->__right_ = __root_; 10614 + __root_->__size_ = prev->__size_ + 1; 10615 + } 10616 + prev = __root_; 10617 + if (__tag_templates_) 10618 + { 10619 + if (__t_end_ == __t_cap_) 10620 + { 10621 + __status_ = memory_alloc_failure; 10622 + return first; 10623 + } 10624 + if (__root_->__left_) 10625 + *__t_end_++ = __root_->__left_; 10626 + else 10627 + *__t_end_++ = __root_; 10628 + } 10629 + t = t2; 10630 + } 10631 + if (t != last && *t == 'E') 10632 + { 10633 + if (__make<__template_args>(name, args)) 10634 + first = t+1; 10635 + } 10636 + } 10637 + return first; 10638 + } 10639 + 10640 + // <substitution> ::= S <seq-id> _ 10641 + // ::= S_ 10642 + // <substitution> ::= Sa # ::std::allocator 10643 + // <substitution> ::= Sb # ::std::basic_string 10644 + // <substitution> ::= Ss # ::std::basic_string < char, 10645 + // ::std::char_traits<char>, 10646 + // ::std::allocator<char> > 10647 + // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > 10648 + // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > 10649 + // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > 10650 + 10651 + const char* 10652 + __demangle_tree::__parse_substitution(const char* first, const char* last) 10653 + { 10654 + if (last - first >= 2) 10655 + { 10656 + if (*first == 'S') 10657 + { 10658 + switch (first[1]) 10659 + { 10660 + case 'a': 10661 + if (__make<__sub_allocator>()) 10662 + first += 2; 10663 + break; 10664 + case 'b': 10665 + if (__make<__sub_basic_string>()) 10666 + first += 2; 10667 + break; 10668 + case 's': 10669 + if (__make<__sub_string>()) 10670 + first += 2; 10671 + break; 10672 + case 'i': 10673 + if (__make<__sub_istream>()) 10674 + first += 2; 10675 + break; 10676 + case 'o': 10677 + if (__make<__sub_ostream>()) 10678 + first += 2; 10679 + break; 10680 + case 'd': 10681 + if (__make<__sub_iostream>()) 10682 + first += 2; 10683 + break; 10684 + case '_': 10685 + if (__sub_begin_ != __sub_end_) 10686 + { 10687 + if (__make<__sub>(*__sub_begin_)) 10688 + first += 2; 10689 + } 10690 + break; 10691 + default: 10692 + if (isdigit(first[1]) || isupper(first[1])) 10693 + { 10694 + size_t sub = 0; 10695 + const char* t = first+1; 10696 + if (isdigit(*t)) 10697 + sub = static_cast<size_t>(*t - '0'); 10698 + else 10699 + sub = static_cast<size_t>(*t - 'A') + 10; 10700 + for (++t; t != last && (isdigit(*t) || isupper(*t)); ++t) 10701 + { 10702 + sub *= 36; 10703 + if (isdigit(*t)) 10704 + sub += static_cast<size_t>(*t - '0'); 10705 + else 10706 + sub += static_cast<size_t>(*t - 'A') + 10; 10707 + } 10708 + if (t == last || *t != '_') 10709 + return first; 10710 + ++sub; 10711 + if (sub < static_cast<size_t>(__sub_end_ - __sub_begin_)) 10712 + { 10713 + if (__make<__sub>(__sub_begin_[sub])) 10714 + first = t+1; 10715 + } 10716 + } 10717 + break; 10718 + } 10719 + } 10720 + } 10721 + return first; 10722 + } 10723 + 10724 + // <name> ::= <nested-name> 10725 + // ::= <local-name> # See Scope Encoding below 10726 + // ::= <unscoped-template-name> <template-args> 10727 + // ::= <unscoped-name> 10728 + 10729 + const char* 10730 + __demangle_tree::__parse_name(const char* first, const char* last) 10731 + { 10732 + if (first != last) 10733 + { 10734 + const char* t0 = first; 10735 + // extension: ignore L here 10736 + if (*t0 == 'L') 10737 + ++t0; 10738 + const char* t = __parse_nested_name(t0, last); 10739 + if (t == t0) 10740 + { 10741 + t = __parse_local_name(t0, last); 10742 + if (t == t0) 10743 + { 10744 + // not <nested-name> nor <local-name> 10745 + // Try to parse <unscoped-template-name> <template-args> or 10746 + // <unscoped-name> which are nearly ambiguous. 10747 + // This logic occurs nowhere else. 10748 + if (last - t0 >= 2) 10749 + { 10750 + if (t0[0] == 'S' && (t0[1] == '_' || 10751 + isdigit(t0[1]) || 10752 + isupper(t0[1]) || 10753 + t0[1] == 'a' || 10754 + t0[1] == 'b')) 10755 + { 10756 + t = __parse_substitution(t0, last); 10757 + if (t != t0) 10758 + { 10759 + const char* t2 = __parse_template_args(t, last); 10760 + if (t2 != t) 10761 + first = t2; 10762 + } 10763 + } 10764 + else // Not a substitution, except maybe St 10765 + { 10766 + t = __parse_unscoped_name(t0, last); 10767 + if (t != t0) 10768 + { 10769 + // unscoped-name might be <unscoped-template-name> 10770 + if (t != last && *t == 'I') 10771 + { 10772 + if (__sub_end_ == __sub_cap_) 10773 + { 10774 + __status_ = memory_alloc_failure; 10775 + return first; 10776 + } 10777 + *__sub_end_++ = __root_; 10778 + const char* t2 = __parse_template_args(t, last); 10779 + if (t2 != t) 10780 + first = t2; 10781 + } 10782 + else 10783 + { 10784 + // <unscoped-name> 10785 + first = t; 10786 + } 10787 + } 10788 + } 10789 + } 10790 + } 10791 + else 10792 + first = t; 10793 + } 10794 + else 10795 + first = t; 10796 + } 10797 + return first; 10798 + } 10799 + 10800 + // extension 10801 + // <dot-suffix> := .<anything and everything> 10802 + 10803 + const char* 10804 + __demangle_tree::__parse_dot_suffix(const char* first, const char* last) 10805 + { 10806 + if (first != last && *first == '.') 10807 + { 10808 + if (__make<__dot_suffix>(__root_, first, static_cast<size_t>(last-first))) 10809 + first = last; 10810 + } 10811 + return first; 10812 + } 10813 + 10814 + // <encoding> ::= <function name> <bare-function-type> 10815 + // ::= <data name> 10816 + // ::= <special-name> 10817 + 10818 + const char* 10819 + __demangle_tree::__parse_encoding(const char* first, const char* last) 10820 + { 10821 + const char* t = __parse_name(first, last); 10822 + if (t != first) 10823 + { 10824 + if (t != last && *t != 'E' && *t != '.') 10825 + { 10826 + __node* name = __root_; 10827 + bool has_return = name->ends_with_template(true) && 10828 + !name->is_ctor_dtor_conv(); 10829 + __node* ret = NULL; 10830 + const char* t2; 10831 + bool prev_tag_templates = __tag_templates_; 10832 + __tag_templates_ = false; 10833 + if (has_return) 10834 + { 10835 + t2 = __parse_type(t, last); 10836 + if (t2 != t) 10837 + { 10838 + ret = __root_; 10839 + t = t2; 10840 + } 10841 + else 10842 + return first; 10843 + } 10844 + t2 = __parse_bare_function_type(t, last); 10845 + if (t2 != t) 10846 + { 10847 + if (dynamic_cast<__void*>(__root_->__left_) != NULL) 10848 + __root_->__left_ = NULL; 10849 + if (__make<__function_signature>(ret, __root_)) 10850 + { 10851 + __node* cv = name->extract_cv(name); 10852 + if (__make<__function>(name, __root_)) 10853 + { 10854 + if (cv) 10855 + { 10856 + cv->__left_ = __root_; 10857 + cv->__size_ <<= 5; 10858 + __root_ = cv; 10859 + } 10860 + first = t2; 10861 + } 10862 + } 10863 + } 10864 + __tag_templates_ = prev_tag_templates; 10865 + } 10866 + else 10867 + first = t; 10868 + } 10869 + else 10870 + first = __parse_special_name(first, last); 10871 + return first; 10872 + } 10873 + 10874 + // <mangled-name> ::= _Z<encoding> 10875 + // ::= <type> 10876 + 10877 + void 10878 + __demangle_tree::__parse() 10879 + { 10880 + if (__mangled_name_begin_ == __mangled_name_end_) 10881 + { 10882 + __status_ = invalid_mangled_name; 10883 + return; 10884 + } 10885 + const char* t = NULL; 10886 + if (__mangled_name_end_ - __mangled_name_begin_ >= 2 && 10887 + __mangled_name_begin_[0] == '_' && 10888 + __mangled_name_begin_[1] == 'Z') 10889 + { 10890 + t = __parse_encoding(__mangled_name_begin_+2, __mangled_name_end_); 10891 + if (t != __mangled_name_begin_+2 && t != __mangled_name_end_ && *t == '.') 10892 + t = __parse_dot_suffix(t, __mangled_name_end_); 10893 + } 10894 + else 10895 + t = __parse_type(__mangled_name_begin_, __mangled_name_end_); 10896 + if (t == __mangled_name_end_ && __root_) 10897 + { 10898 + if (__fix_forward_references_) 10899 + { 10900 + if (__root_->fix_forward_references(__t_begin_, __t_end_)) 10901 + __status_ = success; 10902 + } 10903 + else 10904 + __status_ = success; 10905 + } 10906 + } 10907 + 10908 + __demangle_tree 10909 + __demangle(const char* mangled_name, char* buf, size_t bs) 10910 + { 10911 + __demangle_tree t(mangled_name, buf, bs); 10912 + if (t.__status() == invalid_mangled_name) 10913 + t.__parse(); 10914 + return t; 10915 + } 10916 + 10917 + __demangle_tree 10918 + __demangle(const char* mangled_name) 10919 + { 10920 + return __demangle(mangled_name, 0, 0); 10921 + } 10922 + 10923 + char* 10924 + __demangle(__demangle_tree dmg_tree, char* buf, size_t* n, int* status) 10925 + { 10926 + if (dmg_tree.__status() != success) 10927 + { 10928 + if (status) 10929 + *status = dmg_tree.__status(); 10930 + return NULL; 10931 + } 10932 + #ifdef DEBUGGING 10933 + display(dmg_tree.__root_); 10934 + printf("\n"); 10935 + #endif 10936 + const size_t bs = buf == NULL ? 0 : *n; 10937 + ptrdiff_t sm = dmg_tree.__mangled_name_end_ - dmg_tree.__mangled_name_begin_; 10938 + ptrdiff_t est = sm + 60 * ( 10939 + (dmg_tree.__node_end_ - dmg_tree.__node_begin_) + 10940 + (dmg_tree.__sub_end_ - dmg_tree.__sub_begin_) + 10941 + (dmg_tree.__t_end_ - dmg_tree.__t_begin_)); 10942 + const unsigned N = 4096; 10943 + char tmp[N]; 10944 + ptrdiff_t s; 10945 + if (static_cast<size_t>(est) <= bs) 10946 + { 10947 + char* e = dmg_tree.__get_demangled_name(buf); 10948 + *e++ = '\0'; 10949 + s = e - buf; 10950 + } 10951 + else if (static_cast<size_t>(est) <= N) 10952 + { 10953 + char* e = dmg_tree.__get_demangled_name(tmp); 10954 + *e++ = '\0'; 10955 + s = e - tmp; 10956 + } 10957 + else 10958 + s = static_cast<ptrdiff_t>(dmg_tree.size() + 1); 10959 + if (static_cast<size_t>(s) > bs) 10960 + { 10961 + buf = static_cast<char*>(realloc(buf, static_cast<size_t>(s))); 10962 + if (buf == NULL) 10963 + { 10964 + if (status) 10965 + *status = memory_alloc_failure; 10966 + return NULL; 10967 + } 10968 + if (n) 10969 + *n = static_cast<size_t>(s); 10970 + } 10971 + if (static_cast<size_t>(est) > bs) 10972 + { 10973 + if (static_cast<size_t>(est) <= N) 10974 + strncpy(buf, tmp, static_cast<size_t>(s)); 10975 + else 10976 + *dmg_tree.__get_demangled_name(buf) = '\0'; 10977 + } 10978 + if (status) 10979 + *status = success; 10980 + return buf; 10981 + } 10982 + 10983 + } // __libcxxabi 10984 + 10985 + #pragma GCC visibility pop 10986 + #pragma GCC visibility push(default) 10987 + 10988 + extern "C" 10989 + { 10990 + 10991 + char* 10992 + __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status) 10993 + { 10994 + if (mangled_name == NULL || (buf != NULL && n == NULL)) 10995 + { 10996 + if (status) 10997 + *status = __libcxxabi::invalid_args; 10998 + return NULL; 10999 + } 11000 + const size_t bs = 4 * 1024; 11001 + __attribute((aligned(16))) char static_buf[bs]; 11002 + 11003 + buf = __libcxxabi::__demangle(__libcxxabi::__demangle(mangled_name, 11004 + static_buf, bs), 11005 + buf, n, status); 11006 + return buf; 11007 + } 11008 + 11009 + } // extern "C" 11010 + 11011 + } // abi
+622
src/libunwind-darwin-gcc/src-cxxabi/cxa_exception.cpp
··· 1 + //===------------------------- cxa_exception.cpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Exception Handling APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 11 + // 12 + //===----------------------------------------------------------------------===// 13 + 14 + #include "cxxabi.h" 15 + 16 + #include <exception> // for std::terminate 17 + #include <cstdlib> // for malloc, free 18 + #include <string> // for memset 19 + #include <pthread.h> 20 + 21 + #include "cxa_exception.hpp" 22 + #include "cxa_handlers.hpp" 23 + 24 + // +---------------------------+-----------------------------+---------------+ 25 + // | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object | 26 + // +---------------------------+-----------------------------+---------------+ 27 + // ^ 28 + // | 29 + // +-------------------------------------------------------+ 30 + // | 31 + // +---------------------------+-----------------------------+ 32 + // | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 | 33 + // +---------------------------+-----------------------------+ 34 + 35 + namespace __cxxabiv1 { 36 + 37 + #pragma GCC visibility push(default) 38 + 39 + // Utility routines 40 + static 41 + inline 42 + __cxa_exception* 43 + cxa_exception_from_thrown_object(void* thrown_object) 44 + { 45 + return static_cast<__cxa_exception*>(thrown_object) - 1; 46 + } 47 + 48 + // Note: This is never called when exception_header is masquerading as a 49 + // __cxa_dependent_exception. 50 + static 51 + inline 52 + void* 53 + thrown_object_from_cxa_exception(__cxa_exception* exception_header) 54 + { 55 + return static_cast<void*>(exception_header + 1); 56 + } 57 + 58 + // Get the exception object from the unwind pointer. 59 + // Relies on the structure layout, where the unwind pointer is right in 60 + // front of the user's exception object 61 + static 62 + inline 63 + __cxa_exception* 64 + cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception) 65 + { 66 + return cxa_exception_from_thrown_object(unwind_exception + 1 ); 67 + } 68 + 69 + static 70 + inline 71 + size_t 72 + cxa_exception_size_from_exception_thrown_size(size_t size) 73 + { 74 + return size + sizeof (__cxa_exception); 75 + } 76 + 77 + static void setExceptionClass(_Unwind_Exception* unwind_exception) { 78 + unwind_exception->exception_class = kOurExceptionClass; 79 + } 80 + 81 + static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) { 82 + unwind_exception->exception_class = kOurDependentExceptionClass; 83 + } 84 + 85 + // Is it one of ours? 86 + static bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) { 87 + return (unwind_exception->exception_class & get_vendor_and_language) == 88 + (kOurExceptionClass & get_vendor_and_language); 89 + } 90 + 91 + static bool isDependentException(_Unwind_Exception* unwind_exception) { 92 + return (unwind_exception->exception_class & 0xFF) == 0x01; 93 + } 94 + 95 + // This does not need to be atomic 96 + static inline int incrementHandlerCount(__cxa_exception *exception) { 97 + return ++exception->handlerCount; 98 + } 99 + 100 + // This does not need to be atomic 101 + static inline int decrementHandlerCount(__cxa_exception *exception) { 102 + return --exception->handlerCount; 103 + } 104 + 105 + #include "fallback_malloc.ipp" 106 + 107 + // Allocate some memory from _somewhere_ 108 + static void *do_malloc(size_t size) { 109 + void *ptr = std::malloc(size); 110 + if (NULL == ptr) // if malloc fails, fall back to emergency stash 111 + ptr = fallback_malloc(size); 112 + return ptr; 113 + } 114 + 115 + static void do_free(void *ptr) { 116 + is_fallback_ptr(ptr) ? fallback_free(ptr) : std::free(ptr); 117 + } 118 + 119 + /* 120 + If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler 121 + stored in exc is called. Otherwise the exceptionDestructor stored in 122 + exc is called, and then the memory for the exception is deallocated. 123 + 124 + This is never called for a __cxa_dependent_exception. 125 + */ 126 + static 127 + void 128 + exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) 129 + { 130 + __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception); 131 + if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason) 132 + std::__terminate(exception_header->terminateHandler); 133 + // Just in case there exists a dependent exception that is pointing to this, 134 + // check the reference count and only destroy this if that count goes to zero. 135 + __cxa_decrement_exception_refcount(unwind_exception + 1); 136 + } 137 + 138 + static LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) { 139 + // Section 2.5.3 says: 140 + // * For purposes of this ABI, several things are considered exception handlers: 141 + // ** A terminate() call due to a throw. 142 + // and 143 + // * Upon entry, Following initialization of the catch parameter, 144 + // a handler must call: 145 + // * void *__cxa_begin_catch(void *exceptionObject ); 146 + (void) __cxa_begin_catch(&exception_header->unwindHeader); 147 + std::__terminate(exception_header->terminateHandler); 148 + } 149 + 150 + extern "C" { 151 + 152 + // Allocate a __cxa_exception object, and zero-fill it. 153 + // Reserve "thrown_size" bytes on the end for the user's exception 154 + // object. Zero-fill the object. If memory can't be allocated, call 155 + // std::terminate. Return a pointer to the memory to be used for the 156 + // user's exception object. 157 + void * __cxa_allocate_exception (size_t thrown_size) throw() { 158 + size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size); 159 + __cxa_exception* exception_header = static_cast<__cxa_exception*>(do_malloc(actual_size)); 160 + if (NULL == exception_header) 161 + std::terminate(); 162 + std::memset(exception_header, 0, actual_size); 163 + return thrown_object_from_cxa_exception(exception_header); 164 + } 165 + 166 + 167 + // Free a __cxa_exception object allocated with __cxa_allocate_exception. 168 + void __cxa_free_exception (void * thrown_object) throw() { 169 + do_free(cxa_exception_from_thrown_object(thrown_object)); 170 + } 171 + 172 + 173 + // This function shall allocate a __cxa_dependent_exception and 174 + // return a pointer to it. (Really to the object, not past its' end). 175 + // Otherwise, it will work like __cxa_allocate_exception. 176 + void * __cxa_allocate_dependent_exception () { 177 + size_t actual_size = sizeof(__cxa_dependent_exception); 178 + void *ptr = do_malloc(actual_size); 179 + if (NULL == ptr) 180 + std::terminate(); 181 + std::memset(ptr, 0, actual_size); 182 + return ptr; 183 + } 184 + 185 + 186 + // This function shall free a dependent_exception. 187 + // It does not affect the reference count of the primary exception. 188 + void __cxa_free_dependent_exception (void * dependent_exception) { 189 + do_free(dependent_exception); 190 + } 191 + 192 + 193 + // 2.4.3 Throwing the Exception Object 194 + /* 195 + After constructing the exception object with the throw argument value, 196 + the generated code calls the __cxa_throw runtime library routine. This 197 + routine never returns. 198 + 199 + The __cxa_throw routine will do the following: 200 + 201 + * Obtain the __cxa_exception header from the thrown exception object address, 202 + which can be computed as follows: 203 + __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1); 204 + * Save the current unexpected_handler and terminate_handler in the __cxa_exception header. 205 + * Save the tinfo and dest arguments in the __cxa_exception header. 206 + * Set the exception_class field in the unwind header. This is a 64-bit value 207 + representing the ASCII string "XXXXC++\0", where "XXXX" is a 208 + vendor-dependent string. That is, for implementations conforming to this 209 + ABI, the low-order 4 bytes of this 64-bit value will be "C++\0". 210 + * Increment the uncaught_exception flag. 211 + * Call _Unwind_RaiseException in the system unwind library, Its argument is the 212 + pointer to the thrown exception, which __cxa_throw itself received as an argument. 213 + __Unwind_RaiseException begins the process of stack unwinding, described 214 + in Section 2.5. In special cases, such as an inability to find a 215 + handler, _Unwind_RaiseException may return. In that case, __cxa_throw 216 + will call terminate, assuming that there was no handler for the 217 + exception. 218 + */ 219 + LIBCXXABI_NORETURN 220 + void 221 + __cxa_throw(void* thrown_object, std::type_info* tinfo, void (*dest)(void*)) 222 + { 223 + __cxa_eh_globals *globals = __cxa_get_globals(); 224 + __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); 225 + 226 + exception_header->unexpectedHandler = std::get_unexpected(); 227 + exception_header->terminateHandler = std::get_terminate(); 228 + exception_header->exceptionType = tinfo; 229 + exception_header->exceptionDestructor = dest; 230 + setExceptionClass(&exception_header->unwindHeader); 231 + exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety. 232 + globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local 233 + 234 + exception_header->unwindHeader.exception_cleanup = exception_cleanup_func; 235 + #if __arm__ 236 + _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); 237 + #else 238 + _Unwind_RaiseException(&exception_header->unwindHeader); 239 + #endif 240 + // This only happens when there is no handler, or some unexpected unwinding 241 + // error happens. 242 + failed_throw(exception_header); 243 + } 244 + 245 + 246 + // 2.5.3 Exception Handlers 247 + /* 248 + The adjusted pointer is computed by the personality routine during phase 1 249 + and saved in the exception header (either __cxa_exception or 250 + __cxa_dependent_exception). 251 + 252 + Requires: exception is native 253 + */ 254 + void* 255 + __cxa_get_exception_ptr(void* unwind_exception) throw() 256 + { 257 + return cxa_exception_from_exception_unwind_exception 258 + ( 259 + static_cast<_Unwind_Exception*>(unwind_exception) 260 + )->adjustedPtr; 261 + } 262 + 263 + /* 264 + This routine can catch foreign or native exceptions. If native, the exception 265 + can be a primary or dependent variety. This routine may remain blissfully 266 + ignorant of whether the native exception is primary or dependent. 267 + 268 + If the exception is native: 269 + * Increment's the exception's handler count. 270 + * Push the exception on the stack of currently-caught exceptions if it is not 271 + already there (from a rethrow). 272 + * Decrements the uncaught_exception count. 273 + * Returns the adjusted pointer to the exception object, which is stored in 274 + the __cxa_exception by the personality routine. 275 + 276 + If the exception is foreign, this means it did not originate from one of throw 277 + routines. The foreign exception does not necessarily have a __cxa_exception 278 + header. However we can catch it here with a catch (...), or with a call 279 + to terminate or unexpected during unwinding. 280 + * Do not try to increment the exception's handler count, we don't know where 281 + it is. 282 + * Push the exception on the stack of currently-caught exceptions only if the 283 + stack is empty. The foreign exception has no way to link to the current 284 + top of stack. If the stack is not empty, call terminate. Even with an 285 + empty stack, this is hacked in by pushing a pointer to an imaginary 286 + __cxa_exception block in front of the foreign exception. It would be better 287 + if the __cxa_eh_globals structure had a stack of _Unwind_Exception, but it 288 + doesn't. It has a stack of __cxa_exception (which has a next* in it). 289 + * Do not decrement the uncaught_exception count because we didn't increment it 290 + in __cxa_throw (or one of our rethrow functions). 291 + * If we haven't terminated, assume the exception object is just past the 292 + _Unwind_Exception and return a pointer to that. 293 + */ 294 + void* 295 + __cxa_begin_catch(void* unwind_arg) throw() 296 + { 297 + _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); 298 + bool native_exception = isOurExceptionClass(unwind_exception); 299 + __cxa_eh_globals* globals = __cxa_get_globals(); 300 + // exception_header is a hackish offset from a foreign exception, but it 301 + // works as long as we're careful not to try to access any __cxa_exception 302 + // parts. 303 + __cxa_exception* exception_header = 304 + cxa_exception_from_exception_unwind_exception 305 + ( 306 + static_cast<_Unwind_Exception*>(unwind_exception) 307 + ); 308 + if (native_exception) 309 + { 310 + // Increment the handler count, removing the flag about being rethrown 311 + exception_header->handlerCount = exception_header->handlerCount < 0 ? 312 + -exception_header->handlerCount + 1 : exception_header->handlerCount + 1; 313 + // place the exception on the top of the stack if it's not already 314 + // there by a previous rethrow 315 + if (exception_header != globals->caughtExceptions) 316 + { 317 + exception_header->nextException = globals->caughtExceptions; 318 + globals->caughtExceptions = exception_header; 319 + } 320 + globals->uncaughtExceptions -= 1; // Not atomically, since globals are thread-local 321 + return exception_header->adjustedPtr; 322 + } 323 + // Else this is a foreign exception 324 + // If the caughtExceptions stack is not empty, terminate 325 + if (globals->caughtExceptions != 0) 326 + std::terminate(); 327 + // Push the foreign exception on to the stack 328 + globals->caughtExceptions = exception_header; 329 + return unwind_exception + 1; 330 + } 331 + 332 + 333 + /* 334 + Upon exit for any reason, a handler must call: 335 + void __cxa_end_catch (); 336 + 337 + This routine can be called for either a native or foreign exception. 338 + For a native exception: 339 + * Locates the most recently caught exception and decrements its handler count. 340 + * Removes the exception from the caught exception stack, if the handler count goes to zero. 341 + * If the handler count goes down to zero, and the exception was not re-thrown 342 + by throw, it locates the primary exception (which may be the same as the one 343 + it's handling) and decrements its reference count. If that reference count 344 + goes to zero, the function destroys the exception. In any case, if the current 345 + exception is a dependent exception, it destroys that. 346 + 347 + For a foreign exception: 348 + * If it has been rethrown, there is nothing to do. 349 + * Otherwise delete the exception and pop the catch stack to empty. 350 + */ 351 + void __cxa_end_catch() 352 + { 353 + static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception), 354 + "sizeof(__cxa_exception) must be equal to sizeof(__cxa_dependent_exception)"); 355 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch 356 + __cxa_exception* exception_header = globals->caughtExceptions; 357 + // If we've rethrown a foreign exception, then globals->caughtExceptions 358 + // will have been made an empty stack by __cxa_rethrow() and there is 359 + // nothing more to be done. Do nothing! 360 + if (NULL != exception_header) 361 + { 362 + bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); 363 + if (native_exception) 364 + { 365 + // This is a native exception 366 + if (exception_header->handlerCount < 0) 367 + { 368 + // The exception has been rethrown by __cxa_rethrow, so don't delete it 369 + if (0 == incrementHandlerCount(exception_header)) 370 + { 371 + // Remove from the chain of uncaught exceptions 372 + globals->caughtExceptions = exception_header->nextException; 373 + // but don't destroy 374 + } 375 + // Keep handlerCount negative in case there are nested catch's 376 + // that need to be told that this exception is rethrown. Don't 377 + // erase this rethrow flag until the exception is recaught. 378 + } 379 + else 380 + { 381 + // The native exception has not been rethrown 382 + if (0 == decrementHandlerCount(exception_header)) 383 + { 384 + // Remove from the chain of uncaught exceptions 385 + globals->caughtExceptions = exception_header->nextException; 386 + // Destroy this exception, being careful to distinguish 387 + // between dependent and primary exceptions 388 + if (isDependentException(&exception_header->unwindHeader)) 389 + { 390 + // Reset exception_header to primaryException and deallocate the dependent exception 391 + __cxa_dependent_exception* dep_exception_header = 392 + reinterpret_cast<__cxa_dependent_exception*>(exception_header); 393 + exception_header = 394 + cxa_exception_from_thrown_object(dep_exception_header->primaryException); 395 + __cxa_free_dependent_exception(dep_exception_header); 396 + } 397 + // Destroy the primary exception only if its referenceCount goes to 0 398 + // (this decrement must be atomic) 399 + __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header)); 400 + } 401 + } 402 + } 403 + else 404 + { 405 + // The foreign exception has not been rethrown. Pop the stack 406 + // and delete it. If there are nested catch's and they try 407 + // to touch a foreign exception in any way, that is undefined 408 + // behavior. They likely can't since the only way to catch 409 + // a foreign exception is with catch (...)! 410 + _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader); 411 + globals->caughtExceptions = 0; 412 + } 413 + } 414 + } 415 + 416 + // Note: exception_header may be masquerading as a __cxa_dependent_exception 417 + // and that's ok. exceptionType is there too. 418 + // However watch out for foreign exceptions. Return null for them. 419 + std::type_info * __cxa_current_exception_type() { 420 + // get the current exception 421 + __cxa_eh_globals *globals = __cxa_get_globals_fast(); 422 + if (NULL == globals) 423 + return NULL; // If there have never been any exceptions, there are none now. 424 + __cxa_exception *exception_header = globals->caughtExceptions; 425 + if (NULL == exception_header) 426 + return NULL; // No current exception 427 + if (!isOurExceptionClass(&exception_header->unwindHeader)) 428 + return NULL; 429 + return exception_header->exceptionType; 430 + } 431 + 432 + // 2.5.4 Rethrowing Exceptions 433 + /* This routine can rethrow native or foreign exceptions. 434 + If the exception is native: 435 + * marks the exception object on top of the caughtExceptions stack 436 + (in an implementation-defined way) as being rethrown. 437 + * If the caughtExceptions stack is empty, it calls terminate() 438 + (see [C++FDIS] [except.throw], 15.1.8). 439 + * It then calls _Unwind_RaiseException which should not return 440 + (terminate if it does). 441 + Note: exception_header may be masquerading as a __cxa_dependent_exception 442 + and that's ok. 443 + */ 444 + LIBCXXABI_NORETURN 445 + void 446 + __cxa_rethrow() 447 + { 448 + __cxa_eh_globals* globals = __cxa_get_globals(); 449 + __cxa_exception* exception_header = globals->caughtExceptions; 450 + if (NULL == exception_header) 451 + std::terminate(); // throw; called outside of a exception handler 452 + bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); 453 + if (native_exception) 454 + { 455 + // Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch) 456 + exception_header->handlerCount = -exception_header->handlerCount; 457 + globals->uncaughtExceptions += 1; 458 + // __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary 459 + } 460 + else // this is a foreign exception 461 + { 462 + // The only way to communicate to __cxa_end_catch that we've rethrown 463 + // a foreign exception, so don't delete us, is to pop the stack here 464 + // which must be empty afterwards. Then __cxa_end_catch will do 465 + // nothing 466 + globals->caughtExceptions = 0; 467 + } 468 + #if __arm__ 469 + _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); 470 + #else 471 + _Unwind_RaiseException(&exception_header->unwindHeader); 472 + #endif 473 + 474 + // If we get here, some kind of unwinding error has occurred. 475 + // There is some weird code generation bug happening with 476 + // Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn) 477 + // If we call failed_throw here. Turns up with -O2 or higher, and -Os. 478 + __cxa_begin_catch(&exception_header->unwindHeader); 479 + if (native_exception) 480 + std::__terminate(exception_header->terminateHandler); 481 + // Foreign exception: can't get exception_header->terminateHandler 482 + std::terminate(); 483 + } 484 + 485 + /* 486 + If thrown_object is not null, atomically increment the referenceCount field 487 + of the __cxa_exception header associated with the thrown object referred to 488 + by thrown_object. 489 + 490 + Requires: If thrown_object is not NULL, it is a native exception. 491 + */ 492 + void 493 + __cxa_increment_exception_refcount(void* thrown_object) throw() 494 + { 495 + if (thrown_object != NULL ) 496 + { 497 + __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); 498 + __sync_add_and_fetch(&exception_header->referenceCount, 1); 499 + } 500 + } 501 + 502 + /* 503 + If thrown_object is not null, atomically decrement the referenceCount field 504 + of the __cxa_exception header associated with the thrown object referred to 505 + by thrown_object. If the referenceCount drops to zero, destroy and 506 + deallocate the exception. 507 + 508 + Requires: If thrown_object is not NULL, it is a native exception. 509 + */ 510 + void 511 + __cxa_decrement_exception_refcount(void* thrown_object) throw() 512 + { 513 + if (thrown_object != NULL ) 514 + { 515 + __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); 516 + if (__sync_sub_and_fetch(&exception_header->referenceCount, size_t(1)) == 0) 517 + { 518 + if (NULL != exception_header->exceptionDestructor) 519 + exception_header->exceptionDestructor(thrown_object); 520 + __cxa_free_exception(thrown_object); 521 + } 522 + } 523 + } 524 + 525 + /* 526 + Returns a pointer to the thrown object (if any) at the top of the 527 + caughtExceptions stack. Atommically increment the exception's referenceCount. 528 + If there is no such thrown object or if the thrown object is foreign, 529 + returns null. 530 + 531 + We can use __cxa_get_globals_fast here to get the globals because if there have 532 + been no exceptions thrown, ever, on this thread, we can return NULL without 533 + the need to allocate the exception-handling globals. 534 + */ 535 + void* 536 + __cxa_current_primary_exception() throw() 537 + { 538 + // get the current exception 539 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); 540 + if (NULL == globals) 541 + return NULL; // If there are no globals, there is no exception 542 + __cxa_exception* exception_header = globals->caughtExceptions; 543 + if (NULL == exception_header) 544 + return NULL; // No current exception 545 + if (!isOurExceptionClass(&exception_header->unwindHeader)) 546 + return NULL; // Can't capture a foreign exception (no way to refcount it) 547 + if (isDependentException(&exception_header->unwindHeader)) { 548 + __cxa_dependent_exception* dep_exception_header = 549 + reinterpret_cast<__cxa_dependent_exception*>(exception_header); 550 + exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException); 551 + } 552 + void* thrown_object = thrown_object_from_cxa_exception(exception_header); 553 + __cxa_increment_exception_refcount(thrown_object); 554 + return thrown_object; 555 + } 556 + 557 + /* 558 + If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler 559 + stored in exc is called. Otherwise the referenceCount stored in the 560 + primary exception is decremented, destroying the primary if necessary. 561 + Finally the dependent exception is destroyed. 562 + */ 563 + static 564 + void 565 + dependent_exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) 566 + { 567 + __cxa_dependent_exception* dep_exception_header = 568 + reinterpret_cast<__cxa_dependent_exception*>(unwind_exception + 1) - 1; 569 + if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason) 570 + std::__terminate(dep_exception_header->terminateHandler); 571 + __cxa_decrement_exception_refcount(dep_exception_header->primaryException); 572 + __cxa_free_dependent_exception(dep_exception_header); 573 + } 574 + 575 + /* 576 + If thrown_object is not null, allocate, initialize and thow a dependent 577 + exception. 578 + */ 579 + void 580 + __cxa_rethrow_primary_exception(void* thrown_object) 581 + { 582 + if ( thrown_object != NULL ) 583 + { 584 + // thrown_object guaranteed to be native because 585 + // __cxa_current_primary_exception returns NULL for foreign exceptions 586 + __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); 587 + __cxa_dependent_exception* dep_exception_header = 588 + static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception()); 589 + dep_exception_header->primaryException = thrown_object; 590 + __cxa_increment_exception_refcount(thrown_object); 591 + dep_exception_header->exceptionType = exception_header->exceptionType; 592 + dep_exception_header->unexpectedHandler = std::get_unexpected(); 593 + dep_exception_header->terminateHandler = std::get_terminate(); 594 + setDependentExceptionClass(&dep_exception_header->unwindHeader); 595 + __cxa_get_globals()->uncaughtExceptions += 1; 596 + dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup; 597 + #if __arm__ 598 + _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader); 599 + #else 600 + _Unwind_RaiseException(&dep_exception_header->unwindHeader); 601 + #endif 602 + // Some sort of unwinding error. Note that terminate is a handler. 603 + __cxa_begin_catch(&dep_exception_header->unwindHeader); 604 + } 605 + // If we return client will call terminate() 606 + } 607 + 608 + bool 609 + __cxa_uncaught_exception() throw() 610 + { 611 + // This does not report foreign exceptions in flight 612 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); 613 + if (globals == 0) 614 + return false; 615 + return globals->uncaughtExceptions != 0; 616 + } 617 + 618 + } // extern "C" 619 + 620 + #pragma GCC visibility pop 621 + 622 + } // abi
+123
src/libunwind-darwin-gcc/src-cxxabi/cxa_exception.hpp
··· 1 + //===------------------------- cxa_exception.hpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Exception Handling APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 11 + // 12 + //===----------------------------------------------------------------------===// 13 + 14 + #ifndef _CXA_EXCEPTION_H 15 + #define _CXA_EXCEPTION_H 16 + 17 + #include <exception> // for std::unexpected_handler and std::terminate_handler 18 + #include <cxxabi.h> 19 + #include "unwind.h" 20 + 21 + namespace __cxxabiv1 { 22 + 23 + #pragma GCC visibility push(hidden) 24 + 25 + static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0 26 + static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1 27 + static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++ 28 + 29 + struct __cxa_exception { 30 + #if __LP64__ 31 + // This is a new field to support C++ 0x exception_ptr. 32 + // For binary compatibility it is at the start of this 33 + // struct which is prepended to the object thrown in 34 + // __cxa_allocate_exception. 35 + size_t referenceCount; 36 + #endif 37 + 38 + // Manage the exception object itself. 39 + std::type_info *exceptionType; 40 + void (*exceptionDestructor)(void *); 41 + std::unexpected_handler unexpectedHandler; 42 + std::terminate_handler terminateHandler; 43 + 44 + __cxa_exception *nextException; 45 + 46 + int handlerCount; 47 + 48 + #ifdef __ARM_EABI_UNWINDER__ 49 + __cxa_exception* nextPropagatingException; 50 + int propagationCount; 51 + #else 52 + int handlerSwitchValue; 53 + const unsigned char *actionRecord; 54 + const unsigned char *languageSpecificData; 55 + void *catchTemp; 56 + void *adjustedPtr; 57 + #endif 58 + 59 + #if !__LP64__ 60 + // This is a new field to support C++ 0x exception_ptr. 61 + // For binary compatibility it is placed where the compiler 62 + // previously adding padded to 64-bit align unwindHeader. 63 + size_t referenceCount; 64 + #endif 65 + 66 + _Unwind_Exception unwindHeader; 67 + }; 68 + 69 + // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html 70 + 71 + struct __cxa_dependent_exception { 72 + #if __LP64__ 73 + void* primaryException; 74 + #endif 75 + 76 + std::type_info *exceptionType; 77 + void (*exceptionDestructor)(void *); 78 + std::unexpected_handler unexpectedHandler; 79 + std::terminate_handler terminateHandler; 80 + 81 + __cxa_exception *nextException; 82 + 83 + int handlerCount; 84 + 85 + #ifdef __ARM_EABI_UNWINDER__ 86 + __cxa_exception* nextPropagatingException; 87 + int propagationCount; 88 + #else 89 + int handlerSwitchValue; 90 + const unsigned char *actionRecord; 91 + const unsigned char *languageSpecificData; 92 + void * catchTemp; 93 + void *adjustedPtr; 94 + #endif 95 + 96 + #if !__LP64__ 97 + void* primaryException; 98 + #endif 99 + 100 + _Unwind_Exception unwindHeader; 101 + }; 102 + 103 + struct __cxa_eh_globals { 104 + __cxa_exception * caughtExceptions; 105 + unsigned int uncaughtExceptions; 106 + #ifdef __ARM_EABI_UNWINDER__ 107 + __cxa_exception* propagatingExceptions; 108 + #endif 109 + }; 110 + 111 + #pragma GCC visibility pop 112 + #pragma GCC visibility push(default) 113 + 114 + extern "C" __cxa_eh_globals * __cxa_get_globals (); 115 + extern "C" __cxa_eh_globals * __cxa_get_globals_fast (); 116 + 117 + extern "C" void * __cxa_allocate_dependent_exception (); 118 + extern "C" void __cxa_free_dependent_exception (void * dependent_exception); 119 + 120 + #pragma GCC visibility pop 121 + } 122 + 123 + #endif // _CXA_EXCEPTION_H
+91
src/libunwind-darwin-gcc/src-cxxabi/cxa_exception_storage.cpp
··· 1 + //===--------------------- cxa_exception_storage.cpp ----------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the storage for the "Caught Exception Stack" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html (section 2.2.2) 11 + // 12 + //===----------------------------------------------------------------------===// 13 + 14 + #include "cxa_exception.hpp" 15 + 16 + #ifdef HAS_THREAD_LOCAL 17 + 18 + namespace __cxxabiv1 { 19 + 20 + namespace { 21 + __cxa_eh_globals * __globals () { 22 + static thread_local __cxa_eh_globals eh_globals; 23 + return &eh_globals; 24 + } 25 + } 26 + 27 + extern "C" { 28 + __cxa_eh_globals * __cxa_get_globals () { return __globals (); } 29 + __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); } 30 + } 31 + } 32 + 33 + #else 34 + 35 + #include <pthread.h> 36 + #include <cstdlib> // for calloc, free 37 + #include "abort_message.h" 38 + 39 + // In general, we treat all pthread errors as fatal. 40 + // We cannot call std::terminate() because that will in turn 41 + // call __cxa_get_globals() and cause infinite recursion. 42 + 43 + namespace __cxxabiv1 { 44 + namespace { 45 + pthread_key_t key_; 46 + pthread_once_t flag_ = PTHREAD_ONCE_INIT; 47 + 48 + void destruct_ (void *p) { 49 + std::free ( p ); 50 + if ( 0 != ::pthread_setspecific ( key_, NULL ) ) 51 + abort_message("cannot zero out thread value for __cxa_get_globals()"); 52 + } 53 + 54 + void construct_ () { 55 + if ( 0 != pthread_key_create ( &key_, destruct_ ) ) 56 + abort_message("cannot create pthread key for __cxa_get_globals()"); 57 + } 58 + } 59 + 60 + extern "C" { 61 + __cxa_eh_globals * __cxa_get_globals () { 62 + // Try to get the globals for this thread 63 + __cxa_eh_globals* retVal = __cxa_get_globals_fast (); 64 + 65 + // If this is the first time we've been asked for these globals, create them 66 + if ( NULL == retVal ) { 67 + retVal = static_cast<__cxa_eh_globals*> 68 + (std::calloc (1, sizeof (__cxa_eh_globals))); 69 + if ( NULL == retVal ) 70 + abort_message("cannot allocate __cxa_eh_globals"); 71 + if ( 0 != pthread_setspecific ( key_, retVal ) ) 72 + abort_message("pthread_setspecific failure in __cxa_get_globals()"); 73 + } 74 + return retVal; 75 + } 76 + 77 + // Note that this implementation will reliably return NULL if not 78 + // preceeded by a call to __cxa_get_globals(). This is an extension 79 + // to the Itanium ABI and is taken advantage of in several places in 80 + // libc++abi. 81 + __cxa_eh_globals * __cxa_get_globals_fast () { 82 + // First time through, create the key. 83 + if (0 != pthread_once(&flag_, construct_)) 84 + abort_message("pthread_once failure in __cxa_get_globals_fast()"); 85 + // static int init = construct_(); 86 + return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_)); 87 + } 88 + 89 + } 90 + } 91 + #endif
+231
src/libunwind-darwin-gcc/src-cxxabi/cxa_guard.cpp
··· 1 + //===---------------------------- cxa_guard.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include "abort_message.h" 11 + 12 + #include <pthread.h> 13 + #include <stdint.h> 14 + 15 + /* 16 + This implementation must be careful to not call code external to this file 17 + which will turn around and try to call __cxa_guard_acquire reentrantly. 18 + For this reason, the headers of this file are as restricted as possible. 19 + Previous implementations of this code for __APPLE__ have used 20 + pthread_mutex_lock and the abort_message utility without problem. This 21 + implementation also uses pthread_cond_wait which has tested to not be a 22 + problem. 23 + */ 24 + 25 + namespace __cxxabiv1 26 + { 27 + 28 + namespace 29 + { 30 + 31 + #if __arm__ 32 + 33 + // A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must 34 + // be statically initialized to 0. 35 + typedef uint32_t guard_type; 36 + 37 + // Test the lowest bit. 38 + inline bool is_initialized(guard_type* guard_object) { 39 + return (*guard_object) & 1; 40 + } 41 + 42 + inline void set_initialized(guard_type* guard_object) { 43 + *guard_object |= 1; 44 + } 45 + 46 + #else 47 + 48 + typedef uint64_t guard_type; 49 + 50 + bool is_initialized(guard_type* guard_object) { 51 + char* initialized = (char*)guard_object; 52 + return *initialized; 53 + } 54 + 55 + void set_initialized(guard_type* guard_object) { 56 + char* initialized = (char*)guard_object; 57 + *initialized = 1; 58 + } 59 + 60 + #endif 61 + 62 + pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER; 63 + pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER; 64 + 65 + #if defined(__APPLE__) && !defined(__arm__) 66 + 67 + typedef uint32_t lock_type; 68 + 69 + #if __LITTLE_ENDIAN__ 70 + 71 + inline 72 + lock_type 73 + get_lock(uint64_t x) 74 + { 75 + return static_cast<lock_type>(x >> 32); 76 + } 77 + 78 + inline 79 + void 80 + set_lock(uint64_t& x, lock_type y) 81 + { 82 + x = static_cast<uint64_t>(y) << 32; 83 + } 84 + 85 + #else // __LITTLE_ENDIAN__ 86 + 87 + inline 88 + lock_type 89 + get_lock(uint64_t x) 90 + { 91 + return static_cast<lock_type>(x); 92 + } 93 + 94 + inline 95 + void 96 + set_lock(uint64_t& x, lock_type y) 97 + { 98 + x = y; 99 + } 100 + 101 + #endif // __LITTLE_ENDIAN__ 102 + 103 + #else // !__APPLE__ || __arm__ 104 + 105 + typedef bool lock_type; 106 + 107 + inline 108 + lock_type 109 + get_lock(uint64_t x) 110 + { 111 + union 112 + { 113 + uint64_t guard; 114 + uint8_t lock[2]; 115 + } f = {x}; 116 + return f.lock[1] != 0; 117 + } 118 + 119 + inline 120 + void 121 + set_lock(uint64_t& x, lock_type y) 122 + { 123 + union 124 + { 125 + uint64_t guard; 126 + uint8_t lock[2]; 127 + } f = {0}; 128 + f.lock[1] = y; 129 + x = f.guard; 130 + } 131 + 132 + inline 133 + lock_type 134 + get_lock(uint32_t x) 135 + { 136 + union 137 + { 138 + uint32_t guard; 139 + uint8_t lock[2]; 140 + } f = {x}; 141 + return f.lock[1] != 0; 142 + } 143 + 144 + inline 145 + void 146 + set_lock(uint32_t& x, lock_type y) 147 + { 148 + union 149 + { 150 + uint32_t guard; 151 + uint8_t lock[2]; 152 + } f = {0}; 153 + f.lock[1] = y; 154 + x = f.guard; 155 + } 156 + 157 + #endif // __APPLE__ 158 + 159 + } // unnamed namespace 160 + 161 + extern "C" 162 + { 163 + 164 + int __cxa_guard_acquire(guard_type* guard_object) 165 + { 166 + char* initialized = (char*)guard_object; 167 + if (pthread_mutex_lock(&guard_mut)) 168 + abort_message("__cxa_guard_acquire failed to acquire mutex"); 169 + int result = *initialized == 0; 170 + if (result) 171 + { 172 + #if defined(__APPLE__) && !defined(__arm__) 173 + const lock_type id = pthread_mach_thread_np(pthread_self()); 174 + lock_type lock = get_lock(*guard_object); 175 + if (lock) 176 + { 177 + // if this thread set lock for this same guard_object, abort 178 + if (lock == id) 179 + abort_message("__cxa_guard_acquire detected deadlock"); 180 + do 181 + { 182 + if (pthread_cond_wait(&guard_cv, &guard_mut)) 183 + abort_message("__cxa_guard_acquire condition variable wait failed"); 184 + lock = get_lock(*guard_object); 185 + } while (lock); 186 + result = !is_initialized(guard_object); 187 + if (result) 188 + set_lock(*guard_object, id); 189 + } 190 + else 191 + set_lock(*guard_object, id); 192 + #else // !__APPLE__ || __arm__ 193 + while (get_lock(*guard_object)) 194 + if (pthread_cond_wait(&guard_cv, &guard_mut)) 195 + abort_message("__cxa_guard_acquire condition variable wait failed"); 196 + result = *initialized == 0; 197 + if (result) 198 + set_lock(*guard_object, true); 199 + #endif // !__APPLE__ || __arm__ 200 + } 201 + if (pthread_mutex_unlock(&guard_mut)) 202 + abort_message("__cxa_guard_acquire failed to release mutex"); 203 + return result; 204 + } 205 + 206 + void __cxa_guard_release(guard_type* guard_object) 207 + { 208 + if (pthread_mutex_lock(&guard_mut)) 209 + abort_message("__cxa_guard_release failed to acquire mutex"); 210 + *guard_object = 0; 211 + set_initialized(guard_object); 212 + if (pthread_mutex_unlock(&guard_mut)) 213 + abort_message("__cxa_guard_release failed to release mutex"); 214 + if (pthread_cond_broadcast(&guard_cv)) 215 + abort_message("__cxa_guard_release failed to broadcast condition variable"); 216 + } 217 + 218 + void __cxa_guard_abort(guard_type* guard_object) 219 + { 220 + if (pthread_mutex_lock(&guard_mut)) 221 + abort_message("__cxa_guard_abort failed to acquire mutex"); 222 + *guard_object = 0; 223 + if (pthread_mutex_unlock(&guard_mut)) 224 + abort_message("__cxa_guard_abort failed to release mutex"); 225 + if (pthread_cond_broadcast(&guard_cv)) 226 + abort_message("__cxa_guard_abort failed to broadcast condition variable"); 227 + } 228 + 229 + } // extern "C" 230 + 231 + } // __cxxabiv1
+125
src/libunwind-darwin-gcc/src-cxxabi/cxa_handlers.cpp
··· 1 + //===------------------------- cxa_handlers.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the functionality associated with the terminate_handler, 10 + // unexpected_handler, and new_handler. 11 + //===----------------------------------------------------------------------===// 12 + 13 + #include <stdexcept> 14 + #include <new> 15 + #include <exception> 16 + #include "abort_message.h" 17 + #include "cxxabi.h" 18 + #include "cxa_handlers.hpp" 19 + #include "cxa_exception.hpp" 20 + #include "private_typeinfo.h" 21 + 22 + namespace std 23 + { 24 + 25 + unexpected_handler 26 + get_unexpected() _NOEXCEPT 27 + { 28 + return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0); 29 + // The above is safe but overkill on x86 30 + // Using of C++11 atomics this should be rewritten 31 + // return __cxa_unexpected_handler.load(memory_order_acq); 32 + } 33 + 34 + __attribute__((visibility("hidden"), noreturn)) 35 + void 36 + __unexpected(unexpected_handler func) 37 + { 38 + func(); 39 + // unexpected handler should not return 40 + abort_message("unexpected_handler unexpectedly returned"); 41 + } 42 + 43 + __attribute__((noreturn)) 44 + void 45 + unexpected() 46 + { 47 + __unexpected(get_unexpected()); 48 + } 49 + 50 + terminate_handler 51 + get_terminate() _NOEXCEPT 52 + { 53 + return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0); 54 + // The above is safe but overkill on x86 55 + // Using of C++11 atomics this should be rewritten 56 + // return __cxa_terminate_handler.load(memory_order_acq); 57 + } 58 + 59 + __attribute__((visibility("hidden"), noreturn)) 60 + void 61 + __terminate(terminate_handler func) _NOEXCEPT 62 + { 63 + #if __has_feature(cxx_exceptions) 64 + try 65 + { 66 + #endif // __has_feature(cxx_exceptions) 67 + func(); 68 + // handler should not return 69 + abort_message("terminate_handler unexpectedly returned"); 70 + #if __has_feature(cxx_exceptions) 71 + } 72 + catch (...) 73 + { 74 + // handler should not throw exception 75 + abort_message("terminate_handler unexpectedly threw an exception"); 76 + } 77 + #endif // #if __has_feature(cxx_exceptions) 78 + } 79 + 80 + __attribute__((noreturn)) 81 + void 82 + terminate() _NOEXCEPT 83 + { 84 + // If there might be an uncaught exception 85 + using namespace __cxxabiv1; 86 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); 87 + if (globals) 88 + { 89 + __cxa_exception* exception_header = globals->caughtExceptions; 90 + if (exception_header) 91 + { 92 + _Unwind_Exception* unwind_exception = 93 + reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 94 + bool native_exception = 95 + (unwind_exception->exception_class & get_vendor_and_language) == 96 + (kOurExceptionClass & get_vendor_and_language); 97 + if (native_exception) 98 + __terminate(exception_header->terminateHandler); 99 + } 100 + } 101 + __terminate(get_terminate()); 102 + } 103 + 104 + extern "C" new_handler __cxa_new_handler = 0; 105 + // In the future these will become: 106 + // std::atomic<std::new_handler> __cxa_new_handler(0); 107 + 108 + new_handler 109 + set_new_handler(new_handler handler) _NOEXCEPT 110 + { 111 + return __sync_swap(&__cxa_new_handler, handler); 112 + // Using of C++11 atomics this should be rewritten 113 + // return __cxa_new_handler.exchange(handler, memory_order_acq_rel); 114 + } 115 + 116 + new_handler 117 + get_new_handler() _NOEXCEPT 118 + { 119 + return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0); 120 + // The above is safe but overkill on x86 121 + // Using of C++11 atomics this should be rewritten 122 + // return __cxa_new_handler.load(memory_order_acq); 123 + } 124 + 125 + } // std
+54
src/libunwind-darwin-gcc/src-cxxabi/cxa_handlers.hpp
··· 1 + //===------------------------- cxa_handlers.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the functionality associated with the terminate_handler, 10 + // unexpected_handler, and new_handler. 11 + //===----------------------------------------------------------------------===// 12 + 13 + #ifndef _CXA_HANDLERS_H 14 + #define _CXA_HANDLERS_H 15 + 16 + #include <exception> 17 + 18 + namespace std 19 + { 20 + 21 + __attribute__((visibility("hidden"), noreturn)) 22 + void 23 + __unexpected(unexpected_handler func); 24 + 25 + __attribute__((visibility("hidden"), noreturn)) 26 + void 27 + __terminate(terminate_handler func) _NOEXCEPT; 28 + 29 + } // std 30 + 31 + extern "C" 32 + { 33 + 34 + extern void (*__cxa_terminate_handler)(); 35 + extern void (*__cxa_unexpected_handler)(); 36 + extern void (*__cxa_new_handler)(); 37 + 38 + /* 39 + 40 + At some point in the future these three symbols will become 41 + C++11 atomic variables: 42 + 43 + extern std::atomic<std::terminate_handler> __cxa_terminate_handler; 44 + extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler; 45 + extern std::atomic<std::new_handler> __cxa_new_handler; 46 + 47 + This change will not impact their ABI. But it will allow for a 48 + portible performance optimization. 49 + 50 + */ 51 + 52 + } // extern "C" 53 + 54 + #endif // _CXA_HANDLERS_H
+231
src/libunwind-darwin-gcc/src-cxxabi/cxa_new_delete.cpp
··· 1 + //===------------------------ cxa_new_delete.cpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the new and delete operators. 10 + //===----------------------------------------------------------------------===// 11 + 12 + #include <new> 13 + #include <cstdlib> 14 + 15 + /* 16 + [new.delete.single] 17 + 18 + * Executes a loop: Within the loop, the function first attempts to allocate 19 + the requested storage. Whether the attempt involves a call to the Standard C 20 + library function malloc is unspecified. 21 + 22 + * Returns a pointer to the allocated storage if the attempt is successful. 23 + Otherwise, if the current new_handler (18.6.2.5) is a null pointer value, 24 + throws bad_alloc. 25 + 26 + * Otherwise, the function calls the current new_handler function (18.6.2.3). 27 + If the called function returns, the loop repeats. 28 + 29 + * The loop terminates when an attempt to allocate the requested storage is 30 + successful or when a called new_handler function does not return. 31 + */ 32 + __attribute__((__weak__, __visibility__("default"))) 33 + void * 34 + operator new(std::size_t size) 35 + #if !__has_feature(cxx_noexcept) 36 + throw(std::bad_alloc) 37 + #endif 38 + { 39 + if (size == 0) 40 + size = 1; 41 + void* p; 42 + while ((p = std::malloc(size)) == 0) 43 + { 44 + std::new_handler nh = std::get_new_handler(); 45 + if (nh) 46 + nh(); 47 + else 48 + throw std::bad_alloc(); 49 + } 50 + return p; 51 + } 52 + 53 + /* 54 + Note: The relationships among these operators is both carefully considered 55 + and standard in C++11. Please do not change them without fully understanding 56 + the consequences of doing so. Reference: 57 + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2158.html 58 + */ 59 + /* 60 + [new.delete.single] 61 + 62 + Calls operator new(size). If the call returns normally, returns the result of 63 + that call. Otherwise, returns a null pointer. 64 + */ 65 + __attribute__((__weak__, __visibility__("default"))) 66 + void* 67 + operator new(size_t size, const std::nothrow_t&) 68 + #if __has_feature(cxx_noexcept) 69 + noexcept 70 + #else 71 + throw() 72 + #endif 73 + { 74 + void* p = 0; 75 + try 76 + { 77 + p = ::operator new(size); 78 + } 79 + catch (...) 80 + { 81 + } 82 + return p; 83 + } 84 + 85 + /* 86 + [new.delete.array] 87 + 88 + Returns operator new(size). 89 + */ 90 + __attribute__((__weak__, __visibility__("default"))) 91 + void* 92 + operator new[](size_t size) 93 + #if !__has_feature(cxx_noexcept) 94 + throw(std::bad_alloc) 95 + #endif 96 + { 97 + return ::operator new(size); 98 + } 99 + 100 + /* 101 + [new.delete.array] 102 + 103 + Calls operator new[](size). If the call returns normally, returns the result 104 + of that call. Otherwise, returns a null pointer. 105 + */ 106 + __attribute__((__weak__, __visibility__("default"))) 107 + void* 108 + operator new[](size_t size, const std::nothrow_t&) 109 + #if __has_feature(cxx_noexcept) 110 + noexcept 111 + #else 112 + throw() 113 + #endif 114 + { 115 + void* p = 0; 116 + try 117 + { 118 + p = ::operator new[](size); 119 + } 120 + catch (...) 121 + { 122 + } 123 + return p; 124 + } 125 + 126 + /* 127 + [new.delete.single] 128 + 129 + If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the 130 + earlier call to operator new. 131 + */ 132 + __attribute__((__weak__, __visibility__("default"))) 133 + void 134 + operator delete(void* ptr) 135 + #if __has_feature(cxx_noexcept) 136 + noexcept 137 + #else 138 + throw() 139 + #endif 140 + { 141 + if (ptr) 142 + std::free(ptr); 143 + } 144 + 145 + /* 146 + [new.delete.single] 147 + 148 + calls operator delete(ptr) 149 + */ 150 + __attribute__((__weak__, __visibility__("default"))) 151 + void 152 + operator delete(void* ptr, const std::nothrow_t&) 153 + #if __has_feature(cxx_noexcept) 154 + noexcept 155 + #else 156 + throw() 157 + #endif 158 + { 159 + ::operator delete(ptr); 160 + } 161 + 162 + /* 163 + [new.delete.array] 164 + 165 + Calls operator delete(ptr) 166 + */ 167 + __attribute__((__weak__, __visibility__("default"))) 168 + void 169 + operator delete[] (void* ptr) 170 + #if __has_feature(cxx_noexcept) 171 + noexcept 172 + #else 173 + throw() 174 + #endif 175 + { 176 + ::operator delete(ptr); 177 + } 178 + 179 + /* 180 + [new.delete.array] 181 + 182 + calls operator delete[](ptr) 183 + */ 184 + __attribute__((__weak__, __visibility__("default"))) 185 + void 186 + operator delete[] (void* ptr, const std::nothrow_t&) 187 + #if __has_feature(cxx_noexcept) 188 + noexcept 189 + #else 190 + throw() 191 + #endif 192 + { 193 + ::operator delete[](ptr); 194 + } 195 + 196 + namespace std 197 + { 198 + 199 + // bad_alloc 200 + 201 + bad_alloc::bad_alloc() _NOEXCEPT 202 + { 203 + } 204 + 205 + bad_alloc::~bad_alloc() _NOEXCEPT 206 + { 207 + } 208 + 209 + const char* 210 + bad_alloc::what() const _NOEXCEPT 211 + { 212 + return "std::bad_alloc"; 213 + } 214 + 215 + // bad_array_new_length 216 + 217 + bad_array_new_length::bad_array_new_length() _NOEXCEPT 218 + { 219 + } 220 + 221 + bad_array_new_length::~bad_array_new_length() _NOEXCEPT 222 + { 223 + } 224 + 225 + const char* 226 + bad_array_new_length::what() const _NOEXCEPT 227 + { 228 + return "bad_array_new_length"; 229 + } 230 + 231 + } // std
+1051
src/libunwind-darwin-gcc/src-cxxabi/cxa_personality.cpp
··· 1 + //===------------------------- cxa_exception.cpp --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Exception Handling APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 11 + // http://www.intel.com/design/itanium/downloads/245358.htm 12 + // 13 + //===----------------------------------------------------------------------===// 14 + 15 + #include "unwind.h" 16 + #include "cxa_exception.hpp" 17 + #include "cxa_handlers.hpp" 18 + #include "private_typeinfo.h" 19 + #include <typeinfo> 20 + #include <stdlib.h> 21 + #include <assert.h> 22 + 23 + /* 24 + Exception Header Layout: 25 + 26 + +---------------------------+-----------------------------+---------------+ 27 + | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object | 28 + +---------------------------+-----------------------------+---------------+ 29 + ^ 30 + | 31 + +-------------------------------------------------------+ 32 + | 33 + +---------------------------+-----------------------------+ 34 + | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 | 35 + +---------------------------+-----------------------------+ 36 + 37 + Exception Handling Table Layout: 38 + 39 + +-----------------+--------+ 40 + | lpStartEncoding | (char) | 41 + +---------+-------+--------+---------------+-----------------------+ 42 + | lpStart | (encoded wtih lpStartEncoding) | defaults to funcStart | 43 + +---------+-----+--------+-----------------+---------------+-------+ 44 + | ttypeEncoding | (char) | Encoding of the type_info table | 45 + +---------------+-+------+----+----------------------------+----------------+ 46 + | classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null | 47 + +-----------------++--------+-+----------------------------+----------------+ 48 + | callSiteEncoding | (char) | Encoding for Call Site Table | 49 + +------------------+--+-----+-----+------------------------+--------------------------+ 50 + | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | 51 + +---------------------+-----------+---------------------------------------------------+ 52 + #if !__arm__ 53 + +---------------------+-----------+------------------------------------------------+ 54 + | Beginning of Call Site Table The current ip lies within the | 55 + | ... (start, length) range of one of these | 56 + | call sites. There may be action needed. | 57 + | +-------------+---------------------------------+------------------------------+ | 58 + | | start | (encoded with callSiteEncoding) | offset relative to funcStart | | 59 + | | length | (encoded with callSiteEncoding) | length of code fragment | | 60 + | | landingPad | (encoded with callSiteEncoding) | offset relative to lpStart | | 61 + | | actionEntry | (ULEB128) | Action Table Index 1-based | | 62 + | | | | actionEntry == 0 -> cleanup | | 63 + | +-------------+---------------------------------+------------------------------+ | 64 + | ... | 65 + +----------------------------------------------------------------------------------+ 66 + #else // __arm_ 67 + +---------------------+-----------+------------------------------------------------+ 68 + | Beginning of Call Site Table The current ip is a 1-based index into | 69 + | ... this table. Or it is -1 meaning no | 70 + | action is needed. Or it is 0 meaning | 71 + | terminate. | 72 + | +-------------+---------------------------------+------------------------------+ | 73 + | | landingPad | (ULEB128) | offset relative to lpStart | | 74 + | | actionEntry | (ULEB128) | Action Table Index 1-based | | 75 + | | | | actionEntry == 0 -> cleanup | | 76 + | +-------------+---------------------------------+------------------------------+ | 77 + | ... | 78 + +----------------------------------------------------------------------------------+ 79 + #endif // __arm_ 80 + +---------------------------------------------------------------------+ 81 + | Beginning of Action Table ttypeIndex == 0 : cleanup | 82 + | ... ttypeIndex > 0 : catch | 83 + | ttypeIndex < 0 : exception spec | 84 + | +--------------+-----------+--------------------------------------+ | 85 + | | ttypeIndex | (SLEB128) | Index into type_info Table (1-based) | | 86 + | | actionOffset | (SLEB128) | Offset into next Action Table entry | | 87 + | +--------------+-----------+--------------------------------------+ | 88 + | ... | 89 + +---------------------------------------------------------------------+-----------------+ 90 + | type_info Table, but classInfoOffset does *not* point here! | 91 + | +----------------+------------------------------------------------+-----------------+ | 92 + | | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | | 93 + | +----------------+------------------------------------------------+-----------------+ | 94 + | ... | 95 + | +----------------+------------------------------------------------+-----------------+ | 96 + | | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | | 97 + | +----------------+------------------------------------------------+-----------------+ | 98 + | +---------------------------------------+-----------+------------------------------+ | 99 + | | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! | | 100 + | | ... | (ULEB128) | | | 101 + | | Mth ttypeIndex for 1st exception spec | (ULEB128) | | | 102 + | | 0 | (ULEB128) | | | 103 + | +---------------------------------------+------------------------------------------+ | 104 + | ... | 105 + | +---------------------------------------+------------------------------------------+ | 106 + | | 0 | (ULEB128) | throw() | | 107 + | +---------------------------------------+------------------------------------------+ | 108 + | ... | 109 + | +---------------------------------------+------------------------------------------+ | 110 + | | 1st ttypeIndex for Nth exception spec | (ULEB128) | | | 111 + | | ... | (ULEB128) | | | 112 + | | Mth ttypeIndex for Nth exception spec | (ULEB128) | | | 113 + | | 0 | (ULEB128) | | | 114 + | +---------------------------------------+------------------------------------------+ | 115 + +---------------------------------------------------------------------------------------+ 116 + 117 + Notes: 118 + 119 + * ttypeIndex in the Action Table, and in the exception spec table, is an index, 120 + not a byte count, if positive. It is a negative index offset of 121 + classInfoOffset and the sizeof entry depends on ttypeEncoding. 122 + But if ttypeIndex is negative, it is a positive 1-based byte offset into the 123 + type_info Table. 124 + And if ttypeIndex is zero, it refers to a catch (...). 125 + 126 + * landingPad can be 0, this implies there is nothing to be done. 127 + 128 + * landingPad != 0 and actionEntry == 0 implies a cleanup needs to be done 129 + @landingPad. 130 + 131 + * A cleanup can also be found under landingPad != 0 and actionEntry != 0 in 132 + the Action Table with ttypeIndex == 0. 133 + */ 134 + 135 + namespace __cxxabiv1 136 + { 137 + 138 + extern "C" 139 + { 140 + 141 + // private API 142 + 143 + // Heavily borrowed from llvm/examples/ExceptionDemo/ExceptionDemo.cpp 144 + 145 + // DWARF Constants 146 + enum 147 + { 148 + DW_EH_PE_absptr = 0x00, 149 + DW_EH_PE_uleb128 = 0x01, 150 + DW_EH_PE_udata2 = 0x02, 151 + DW_EH_PE_udata4 = 0x03, 152 + DW_EH_PE_udata8 = 0x04, 153 + DW_EH_PE_sleb128 = 0x09, 154 + DW_EH_PE_sdata2 = 0x0A, 155 + DW_EH_PE_sdata4 = 0x0B, 156 + DW_EH_PE_sdata8 = 0x0C, 157 + DW_EH_PE_pcrel = 0x10, 158 + DW_EH_PE_textrel = 0x20, 159 + DW_EH_PE_datarel = 0x30, 160 + DW_EH_PE_funcrel = 0x40, 161 + DW_EH_PE_aligned = 0x50, 162 + DW_EH_PE_indirect = 0x80, 163 + DW_EH_PE_omit = 0xFF 164 + }; 165 + 166 + /// Read a uleb128 encoded value and advance pointer 167 + /// See Variable Length Data Appendix C in: 168 + /// @link http://dwarfstd.org/Dwarf4.pdf @unlink 169 + /// @param data reference variable holding memory pointer to decode from 170 + /// @returns decoded value 171 + static 172 + uintptr_t 173 + readULEB128(const uint8_t** data) 174 + { 175 + uintptr_t result = 0; 176 + uintptr_t shift = 0; 177 + unsigned char byte; 178 + const uint8_t *p = *data; 179 + do 180 + { 181 + byte = *p++; 182 + result |= static_cast<uintptr_t>(byte & 0x7F) << shift; 183 + shift += 7; 184 + } while (byte & 0x80); 185 + *data = p; 186 + return result; 187 + } 188 + 189 + /// Read a sleb128 encoded value and advance pointer 190 + /// See Variable Length Data Applendix C in: 191 + /// @link http://dwarfstd.org/Dwarf4.pdf @unlink 192 + /// @param data reference variable holding memory pointer to decode from 193 + /// @returns decoded value 194 + static 195 + intptr_t 196 + readSLEB128(const uint8_t** data) 197 + { 198 + uintptr_t result = 0; 199 + uintptr_t shift = 0; 200 + unsigned char byte; 201 + const uint8_t *p = *data; 202 + do 203 + { 204 + byte = *p++; 205 + result |= static_cast<uintptr_t>(byte & 0x7F) << shift; 206 + shift += 7; 207 + } while (byte & 0x80); 208 + *data = p; 209 + if ((byte & 0x40) && (shift < (sizeof(result) << 3))) 210 + result |= static_cast<uintptr_t>(~0) << shift; 211 + return static_cast<intptr_t>(result); 212 + } 213 + 214 + /// Read a pointer encoded value and advance pointer 215 + /// See Variable Length Data in: 216 + /// @link http://dwarfstd.org/Dwarf3.pdf @unlink 217 + /// @param data reference variable holding memory pointer to decode from 218 + /// @param encoding dwarf encoding type 219 + /// @returns decoded value 220 + static 221 + uintptr_t 222 + readEncodedPointer(const uint8_t** data, uint8_t encoding) 223 + { 224 + uintptr_t result = 0; 225 + if (encoding == DW_EH_PE_omit) 226 + return result; 227 + const uint8_t* p = *data; 228 + // first get value 229 + switch (encoding & 0x0F) 230 + { 231 + case DW_EH_PE_absptr: 232 + result = *((uintptr_t*)p); 233 + p += sizeof(uintptr_t); 234 + break; 235 + case DW_EH_PE_uleb128: 236 + result = readULEB128(&p); 237 + break; 238 + case DW_EH_PE_sleb128: 239 + result = static_cast<uintptr_t>(readSLEB128(&p)); 240 + break; 241 + case DW_EH_PE_udata2: 242 + result = *((uint16_t*)p); 243 + p += sizeof(uint16_t); 244 + break; 245 + case DW_EH_PE_udata4: 246 + result = *((uint32_t*)p); 247 + p += sizeof(uint32_t); 248 + break; 249 + case DW_EH_PE_udata8: 250 + result = static_cast<uintptr_t>(*((uint64_t*)p)); 251 + p += sizeof(uint64_t); 252 + break; 253 + case DW_EH_PE_sdata2: 254 + result = static_cast<uintptr_t>(*((int16_t*)p)); 255 + p += sizeof(int16_t); 256 + break; 257 + case DW_EH_PE_sdata4: 258 + result = static_cast<uintptr_t>(*((int32_t*)p)); 259 + p += sizeof(int32_t); 260 + break; 261 + case DW_EH_PE_sdata8: 262 + result = static_cast<uintptr_t>(*((int64_t*)p)); 263 + p += sizeof(int64_t); 264 + break; 265 + default: 266 + // not supported 267 + abort(); 268 + break; 269 + } 270 + // then add relative offset 271 + switch (encoding & 0x70) 272 + { 273 + case DW_EH_PE_absptr: 274 + // do nothing 275 + break; 276 + case DW_EH_PE_pcrel: 277 + if (result) 278 + result += (uintptr_t)(*data); 279 + break; 280 + case DW_EH_PE_textrel: 281 + case DW_EH_PE_datarel: 282 + case DW_EH_PE_funcrel: 283 + case DW_EH_PE_aligned: 284 + default: 285 + // not supported 286 + abort(); 287 + break; 288 + } 289 + // then apply indirection 290 + if (result && (encoding & DW_EH_PE_indirect)) 291 + result = *((uintptr_t*)result); 292 + *data = p; 293 + return result; 294 + } 295 + 296 + static 297 + void 298 + call_terminate(bool native_exception, _Unwind_Exception* unwind_exception) 299 + { 300 + __cxa_begin_catch(unwind_exception); 301 + if (native_exception) 302 + { 303 + // Use the stored terminate_handler if possible 304 + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 305 + std::__terminate(exception_header->terminateHandler); 306 + } 307 + std::terminate(); 308 + } 309 + 310 + static 311 + const __shim_type_info* 312 + get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, 313 + uint8_t ttypeEncoding, bool native_exception, 314 + _Unwind_Exception* unwind_exception) 315 + { 316 + if (classInfo == 0) 317 + { 318 + // this should not happen. Indicates corrupted eh_table. 319 + call_terminate(native_exception, unwind_exception); 320 + } 321 + switch (ttypeEncoding & 0x0F) 322 + { 323 + case DW_EH_PE_absptr: 324 + ttypeIndex *= sizeof(void*); 325 + break; 326 + case DW_EH_PE_udata2: 327 + case DW_EH_PE_sdata2: 328 + ttypeIndex *= 2; 329 + break; 330 + case DW_EH_PE_udata4: 331 + case DW_EH_PE_sdata4: 332 + ttypeIndex *= 4; 333 + break; 334 + case DW_EH_PE_udata8: 335 + case DW_EH_PE_sdata8: 336 + ttypeIndex *= 8; 337 + break; 338 + default: 339 + // this should not happen. Indicates corrupted eh_table. 340 + call_terminate(native_exception, unwind_exception); 341 + } 342 + classInfo -= ttypeIndex; 343 + return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding); 344 + } 345 + 346 + /* 347 + This is checking a thrown exception type, excpType, against a posibly empty 348 + list of catchType's which make up an exception spec. 349 + 350 + An exception spec acts like a catch handler, but in reverse. This "catch 351 + handler" will catch an excpType if and only if none of the catchType's in 352 + the list will catch a excpType. If any catchType in the list can catch an 353 + excpType, then this exception spec does not catch the excpType. 354 + */ 355 + static 356 + bool 357 + exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo, 358 + uint8_t ttypeEncoding, const __shim_type_info* excpType, 359 + void* adjustedPtr, _Unwind_Exception* unwind_exception) 360 + { 361 + if (classInfo == 0) 362 + { 363 + // this should not happen. Indicates corrupted eh_table. 364 + call_terminate(false, unwind_exception); 365 + } 366 + // specIndex is negative of 1-based byte offset into classInfo; 367 + specIndex = -specIndex; 368 + --specIndex; 369 + const uint8_t* temp = classInfo + specIndex; 370 + // If any type in the spec list can catch excpType, return false, else return true 371 + // adjustments to adjustedPtr are ignored. 372 + while (true) 373 + { 374 + uint64_t ttypeIndex = readULEB128(&temp); 375 + if (ttypeIndex == 0) 376 + break; 377 + const __shim_type_info* catchType = get_shim_type_info(ttypeIndex, 378 + classInfo, 379 + ttypeEncoding, 380 + true, 381 + unwind_exception); 382 + void* tempPtr = adjustedPtr; 383 + if (catchType->can_catch(excpType, tempPtr)) 384 + return false; 385 + } 386 + return true; 387 + } 388 + 389 + static 390 + void* 391 + get_thrown_object_ptr(_Unwind_Exception* unwind_exception) 392 + { 393 + // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1 394 + // Regardless, this library is prohibited from touching a foreign exception 395 + void* adjustedPtr = unwind_exception + 1; 396 + if (unwind_exception->exception_class == kOurDependentExceptionClass) 397 + adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException; 398 + return adjustedPtr; 399 + } 400 + 401 + namespace 402 + { 403 + 404 + struct scan_results 405 + { 406 + int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup 407 + const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. 408 + const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected 409 + uintptr_t landingPad; // null -> nothing found, else something found 410 + void* adjustedPtr; // Used in cxa_exception.cpp 411 + _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, 412 + // _URC_FATAL_PHASE2_ERROR, 413 + // _URC_CONTINUE_UNWIND, 414 + // _URC_HANDLER_FOUND 415 + }; 416 + 417 + } // unnamed namespace 418 + 419 + static 420 + void 421 + set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, 422 + const scan_results& results) 423 + { 424 + #if __arm__ 425 + _Unwind_SetGR(context, 0, reinterpret_cast<uintptr_t>(unwind_exception)); 426 + _Unwind_SetGR(context, 1, static_cast<uintptr_t>(results.ttypeIndex)); 427 + #else 428 + _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), 429 + reinterpret_cast<uintptr_t>(unwind_exception)); 430 + _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 431 + static_cast<uintptr_t>(results.ttypeIndex)); 432 + #endif 433 + _Unwind_SetIP(context, results.landingPad); 434 + } 435 + 436 + /* 437 + There are 3 types of scans needed: 438 + 439 + 1. Scan for handler with native or foreign exception. If handler found, 440 + save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. 441 + May also report an error on invalid input. 442 + May terminate for invalid exception table. 443 + _UA_SEARCH_PHASE 444 + 445 + 2. Scan for handler with foreign exception. Must return _URC_HANDLER_FOUND, 446 + or call terminate. 447 + _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception 448 + 449 + 3. Scan for cleanups. If a handler is found and this isn't forced unwind, 450 + then terminate, otherwise ignore the handler and keep looking for cleanup. 451 + If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. 452 + May also report an error on invalid input. 453 + May terminate for invalid exception table. 454 + _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME 455 + */ 456 + 457 + static 458 + void 459 + scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception, 460 + _Unwind_Exception* unwind_exception, _Unwind_Context* context) 461 + { 462 + // Initialize results to found nothing but an error 463 + results.ttypeIndex = 0; 464 + results.actionRecord = 0; 465 + results.languageSpecificData = 0; 466 + results.landingPad = 0; 467 + results.adjustedPtr = 0; 468 + results.reason = _URC_FATAL_PHASE1_ERROR; 469 + // Check for consistent actions 470 + if (actions & _UA_SEARCH_PHASE) 471 + { 472 + // Do Phase 1 473 + if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) 474 + { 475 + // None of these flags should be set during Phase 1 476 + // Client error 477 + results.reason = _URC_FATAL_PHASE1_ERROR; 478 + return; 479 + } 480 + } 481 + else if (actions & _UA_CLEANUP_PHASE) 482 + { 483 + if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) 484 + { 485 + // _UA_HANDLER_FRAME should only be set if phase 1 found a handler. 486 + // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened. 487 + // Client error 488 + results.reason = _URC_FATAL_PHASE2_ERROR; 489 + return; 490 + } 491 + } 492 + else // Niether _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set 493 + { 494 + // One of these should be set. 495 + // Client error 496 + results.reason = _URC_FATAL_PHASE1_ERROR; 497 + return; 498 + } 499 + // Start scan by getting exception table address 500 + const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context); 501 + if (lsda == 0) 502 + { 503 + // There is no exception table 504 + results.reason = _URC_CONTINUE_UNWIND; 505 + return; 506 + } 507 + results.languageSpecificData = lsda; 508 + // Get the current instruction pointer and offset it before next 509 + // instruction in the current frame which threw the exception. 510 + uintptr_t ip = _Unwind_GetIP(context) - 1; 511 + // Get beginning current frame's code (as defined by the 512 + // emitted dwarf code) 513 + uintptr_t funcStart = _Unwind_GetRegionStart(context); 514 + #if __arm__ 515 + if (ip == uintptr_t(-1)) 516 + { 517 + // no action 518 + results.reason = _URC_CONTINUE_UNWIND; 519 + return; 520 + } 521 + else if (ip == 0) 522 + call_terminate(native_exception, unwind_exception); 523 + // ip is 1-based index into call site table 524 + #else // __arm__ 525 + uintptr_t ipOffset = ip - funcStart; 526 + #endif // __arm__ 527 + const uint8_t* classInfo = NULL; 528 + // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding 529 + // dwarf emission 530 + // Parse LSDA header. 531 + uint8_t lpStartEncoding = *lsda++; 532 + const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); 533 + if (lpStart == 0) 534 + lpStart = (const uint8_t*)funcStart; 535 + uint8_t ttypeEncoding = *lsda++; 536 + if (ttypeEncoding != DW_EH_PE_omit) 537 + { 538 + // Calculate type info locations in emitted dwarf code which 539 + // were flagged by type info arguments to llvm.eh.selector 540 + // intrinsic 541 + uintptr_t classInfoOffset = readULEB128(&lsda); 542 + classInfo = lsda + classInfoOffset; 543 + } 544 + // Walk call-site table looking for range that 545 + // includes current PC. 546 + uint8_t callSiteEncoding = *lsda++; 547 + #if __arm__ 548 + (void)callSiteEncoding; // On arm callSiteEncoding is never used 549 + #endif 550 + uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda)); 551 + const uint8_t* callSiteTableStart = lsda; 552 + const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength; 553 + const uint8_t* actionTableStart = callSiteTableEnd; 554 + const uint8_t* callSitePtr = callSiteTableStart; 555 + while (true) 556 + { 557 + // There is one entry per call site. 558 + #if !__arm__ 559 + // The call sites are non-overlapping in [start, start+length) 560 + // The call sites are ordered in increasing value of start 561 + uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding); 562 + uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding); 563 + uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); 564 + uintptr_t actionEntry = readULEB128(&callSitePtr); 565 + if ((start <= ipOffset) && (ipOffset < (start + length))) 566 + #else // __arm__ 567 + // ip is 1-based index into this table 568 + uintptr_t landingPad = readULEB128(&callSitePtr); 569 + uintptr_t actionEntry = readULEB128(&callSitePtr); 570 + if (--ip == 0) 571 + #endif // __arm__ 572 + { 573 + // Found the call site containing ip. 574 + #if !__arm__ 575 + if (landingPad == 0) 576 + { 577 + // No handler here 578 + results.reason = _URC_CONTINUE_UNWIND; 579 + return; 580 + } 581 + landingPad = (uintptr_t)lpStart + landingPad; 582 + #else // __arm__ 583 + ++landingPad; 584 + #endif // __arm__ 585 + if (actionEntry == 0) 586 + { 587 + // Found a cleanup 588 + // If this is a type 1 or type 2 search, there are no handlers 589 + // If this is a type 3 search, you want to install the cleanup. 590 + if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) 591 + { 592 + results.ttypeIndex = 0; // Redundant but clarifying 593 + results.landingPad = landingPad; 594 + results.reason = _URC_HANDLER_FOUND; 595 + return; 596 + } 597 + // No handler here 598 + results.reason = _URC_CONTINUE_UNWIND; 599 + return; 600 + } 601 + // Convert 1-based byte offset into 602 + const uint8_t* action = actionTableStart + (actionEntry - 1); 603 + // Scan action entries until you find a matching handler, cleanup, or the end of action list 604 + while (true) 605 + { 606 + const uint8_t* actionRecord = action; 607 + int64_t ttypeIndex = readSLEB128(&action); 608 + if (ttypeIndex > 0) 609 + { 610 + // Found a catch, does it actually catch? 611 + // First check for catch (...) 612 + const __shim_type_info* catchType = 613 + get_shim_type_info(static_cast<uint64_t>(ttypeIndex), 614 + classInfo, ttypeEncoding, 615 + native_exception, unwind_exception); 616 + if (catchType == 0) 617 + { 618 + // Found catch (...) catches everything, including foreign exceptions 619 + // If this is a type 1 search save state and return _URC_HANDLER_FOUND 620 + // If this is a type 2 search save state and return _URC_HANDLER_FOUND 621 + // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 622 + // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 623 + if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) 624 + { 625 + // Save state and return _URC_HANDLER_FOUND 626 + results.ttypeIndex = ttypeIndex; 627 + results.actionRecord = actionRecord; 628 + results.landingPad = landingPad; 629 + results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 630 + results.reason = _URC_HANDLER_FOUND; 631 + return; 632 + } 633 + else if (!(actions & _UA_FORCE_UNWIND)) 634 + { 635 + // It looks like the exception table has changed 636 + // on us. Likely stack corruption! 637 + call_terminate(native_exception, unwind_exception); 638 + } 639 + } 640 + // Else this is a catch (T) clause and will never 641 + // catch a foreign exception 642 + else if (native_exception) 643 + { 644 + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 645 + void* adjustedPtr = get_thrown_object_ptr(unwind_exception); 646 + const __shim_type_info* excpType = 647 + static_cast<const __shim_type_info*>(exception_header->exceptionType); 648 + if (adjustedPtr == 0 || excpType == 0) 649 + { 650 + // Something very bad happened 651 + call_terminate(native_exception, unwind_exception); 652 + } 653 + if (catchType->can_catch(excpType, adjustedPtr)) 654 + { 655 + // Found a matching handler 656 + // If this is a type 1 search save state and return _URC_HANDLER_FOUND 657 + // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1! 658 + // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan 659 + if (actions & _UA_SEARCH_PHASE) 660 + { 661 + // Save state and return _URC_HANDLER_FOUND 662 + results.ttypeIndex = ttypeIndex; 663 + results.actionRecord = actionRecord; 664 + results.landingPad = landingPad; 665 + results.adjustedPtr = adjustedPtr; 666 + results.reason = _URC_HANDLER_FOUND; 667 + return; 668 + } 669 + else if (!(actions & _UA_FORCE_UNWIND)) 670 + { 671 + // It looks like the exception table has changed 672 + // on us. Likely stack corruption! 673 + call_terminate(native_exception, unwind_exception); 674 + } 675 + } 676 + } 677 + // Scan next action ... 678 + } 679 + else if (ttypeIndex < 0) 680 + { 681 + // Found an exception spec. If this is a foreign exception, 682 + // it is always caught. 683 + if (native_exception) 684 + { 685 + // Does the exception spec catch this native exception? 686 + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 687 + void* adjustedPtr = get_thrown_object_ptr(unwind_exception); 688 + const __shim_type_info* excpType = 689 + static_cast<const __shim_type_info*>(exception_header->exceptionType); 690 + if (adjustedPtr == 0 || excpType == 0) 691 + { 692 + // Something very bad happened 693 + call_terminate(native_exception, unwind_exception); 694 + } 695 + if (exception_spec_can_catch(ttypeIndex, classInfo, 696 + ttypeEncoding, excpType, 697 + adjustedPtr, unwind_exception)) 698 + { 699 + // native exception caught by exception spec 700 + // If this is a type 1 search, save state and return _URC_HANDLER_FOUND 701 + // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 702 + // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 703 + if (actions & _UA_SEARCH_PHASE) 704 + { 705 + // Save state and return _URC_HANDLER_FOUND 706 + results.ttypeIndex = ttypeIndex; 707 + results.actionRecord = actionRecord; 708 + results.landingPad = landingPad; 709 + results.adjustedPtr = adjustedPtr; 710 + results.reason = _URC_HANDLER_FOUND; 711 + return; 712 + } 713 + else if (!(actions & _UA_FORCE_UNWIND)) 714 + { 715 + // It looks like the exception table has changed 716 + // on us. Likely stack corruption! 717 + call_terminate(native_exception, unwind_exception); 718 + } 719 + } 720 + } 721 + else 722 + { 723 + // foreign exception caught by exception spec 724 + // If this is a type 1 search, save state and return _URC_HANDLER_FOUND 725 + // If this is a type 2 search, save state and return _URC_HANDLER_FOUND 726 + // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 727 + // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 728 + if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) 729 + { 730 + // Save state and return _URC_HANDLER_FOUND 731 + results.ttypeIndex = ttypeIndex; 732 + results.actionRecord = actionRecord; 733 + results.landingPad = landingPad; 734 + results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 735 + results.reason = _URC_HANDLER_FOUND; 736 + return; 737 + } 738 + else if (!(actions & _UA_FORCE_UNWIND)) 739 + { 740 + // It looks like the exception table has changed 741 + // on us. Likely stack corruption! 742 + call_terminate(native_exception, unwind_exception); 743 + } 744 + } 745 + // Scan next action ... 746 + } 747 + else // ttypeIndex == 0 748 + { 749 + // Found a cleanup 750 + // If this is a type 1 search, ignore it and continue scan 751 + // If this is a type 2 search, ignore it and continue scan 752 + // If this is a type 3 search, save state and return _URC_HANDLER_FOUND 753 + if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) 754 + { 755 + // Save state and return _URC_HANDLER_FOUND 756 + results.ttypeIndex = ttypeIndex; 757 + results.actionRecord = actionRecord; 758 + results.landingPad = landingPad; 759 + results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 760 + results.reason = _URC_HANDLER_FOUND; 761 + return; 762 + } 763 + } 764 + const uint8_t* temp = action; 765 + int64_t actionOffset = readSLEB128(&temp); 766 + if (actionOffset == 0) 767 + { 768 + // End of action list, no matching handler or cleanup found 769 + results.reason = _URC_CONTINUE_UNWIND; 770 + return; 771 + } 772 + // Go to next action 773 + action += actionOffset; 774 + } // there is no break out of this loop, only return 775 + } 776 + #if !__arm__ 777 + else if (ipOffset < start) 778 + { 779 + // There is no call site for this ip 780 + // Something bad has happened. We should never get here. 781 + // Possible stack corruption. 782 + call_terminate(native_exception, unwind_exception); 783 + } 784 + #endif // !__arm__ 785 + } // there is no break out of this loop, only return 786 + } 787 + 788 + // public API 789 + 790 + /* 791 + The personality function branches on actions like so: 792 + 793 + _UA_SEARCH_PHASE 794 + 795 + If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's 796 + an error from above, return _URC_FATAL_PHASE1_ERROR. 797 + 798 + Scan for anything that could stop unwinding: 799 + 800 + 1. A catch clause that will catch this exception 801 + (will never catch foreign). 802 + 2. A catch (...) (will always catch foreign). 803 + 3. An exception spec that will catch this exception 804 + (will always catch foreign). 805 + If a handler is found 806 + If not foreign 807 + Save state in header 808 + return _URC_HANDLER_FOUND 809 + Else a handler not found 810 + return _URC_CONTINUE_UNWIND 811 + 812 + _UA_CLEANUP_PHASE 813 + 814 + If _UA_HANDLER_FRAME 815 + If _UA_FORCE_UNWIND 816 + How did this happen? return _URC_FATAL_PHASE2_ERROR 817 + If foreign 818 + Do _UA_SEARCH_PHASE to recover state 819 + else 820 + Recover state from header 821 + Transfer control to landing pad. return _URC_INSTALL_CONTEXT 822 + 823 + Else 824 + 825 + This branch handles both normal C++ non-catching handlers (cleanups) 826 + and forced unwinding. 827 + Scan for anything that can not stop unwinding: 828 + 829 + 1. A cleanup. 830 + 831 + If a cleanup is found 832 + transfer control to it. return _URC_INSTALL_CONTEXT 833 + Else a cleanup is not found: return _URC_CONTINUE_UNWIND 834 + */ 835 + 836 + _Unwind_Reason_Code 837 + #if __arm__ 838 + __gxx_personality_sj0 839 + #else 840 + __gxx_personality_v0 841 + #endif 842 + (int version, _Unwind_Action actions, uint64_t exceptionClass, 843 + _Unwind_Exception* unwind_exception, _Unwind_Context* context) 844 + { 845 + if (version != 1 || unwind_exception == 0 || context == 0) 846 + return _URC_FATAL_PHASE1_ERROR; 847 + bool native_exception = (exceptionClass & get_vendor_and_language) == 848 + (kOurExceptionClass & get_vendor_and_language); 849 + scan_results results; 850 + if (actions & _UA_SEARCH_PHASE) 851 + { 852 + // Phase 1 search: All we're looking for in phase 1 is a handler that 853 + // halts unwinding 854 + scan_eh_tab(results, actions, native_exception, unwind_exception, context); 855 + if (results.reason == _URC_HANDLER_FOUND) 856 + { 857 + // Found one. Can we cache the results somewhere to optimize phase 2? 858 + if (native_exception) 859 + { 860 + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 861 + exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex); 862 + exception_header->actionRecord = results.actionRecord; 863 + exception_header->languageSpecificData = results.languageSpecificData; 864 + exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad); 865 + exception_header->adjustedPtr = results.adjustedPtr; 866 + } 867 + return _URC_HANDLER_FOUND; 868 + } 869 + // Did not find a catching-handler. Return the results of the scan 870 + // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR 871 + // if we were called improperly). 872 + return results.reason; 873 + } 874 + if (actions & _UA_CLEANUP_PHASE) 875 + { 876 + // Phase 2 search: 877 + // Did we find a catching handler in phase 1? 878 + if (actions & _UA_HANDLER_FRAME) 879 + { 880 + // Yes, phase 1 said we have a catching handler here. 881 + // Did we cache the results of the scan? 882 + if (native_exception) 883 + { 884 + // Yes, reload the results from the cache. 885 + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 886 + results.ttypeIndex = exception_header->handlerSwitchValue; 887 + results.actionRecord = exception_header->actionRecord; 888 + results.languageSpecificData = exception_header->languageSpecificData; 889 + results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp); 890 + results.adjustedPtr = exception_header->adjustedPtr; 891 + } 892 + else 893 + { 894 + // No, do the scan again to reload the results. 895 + scan_eh_tab(results, actions, native_exception, unwind_exception, context); 896 + // Phase 1 told us we would find a handler. Now in Phase 2 we 897 + // didn't find a handler. The eh table should not be changing! 898 + if (results.reason != _URC_HANDLER_FOUND) 899 + call_terminate(native_exception, unwind_exception); 900 + } 901 + // Jump to the handler 902 + set_registers(unwind_exception, context, results); 903 + return _URC_INSTALL_CONTEXT; 904 + } 905 + // Either we didn't do a phase 1 search (due to forced unwinding), or 906 + // phase 1 reported no catching-handlers. 907 + // Search for a (non-catching) cleanup 908 + scan_eh_tab(results, actions, native_exception, unwind_exception, context); 909 + if (results.reason == _URC_HANDLER_FOUND) 910 + { 911 + // Found a non-catching handler. Jump to it: 912 + set_registers(unwind_exception, context, results); 913 + return _URC_INSTALL_CONTEXT; 914 + } 915 + // Did not find a cleanup. Return the results of the scan 916 + // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR 917 + // if we were called improperly). 918 + return results.reason; 919 + } 920 + // We were called improperly: neither a phase 1 or phase 2 search 921 + return _URC_FATAL_PHASE1_ERROR; 922 + } 923 + 924 + __attribute__((noreturn)) 925 + void 926 + __cxa_call_unexpected(void* arg) 927 + { 928 + _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg); 929 + if (unwind_exception == 0) 930 + call_terminate(false, unwind_exception); 931 + __cxa_begin_catch(unwind_exception); 932 + bool native_old_exception = 933 + (unwind_exception->exception_class & get_vendor_and_language) == 934 + (kOurExceptionClass & get_vendor_and_language); 935 + std::unexpected_handler u_handler; 936 + std::terminate_handler t_handler; 937 + __cxa_exception* old_exception_header = 0; 938 + int64_t ttypeIndex; 939 + const uint8_t* lsda; 940 + if (native_old_exception) 941 + { 942 + old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 943 + t_handler = old_exception_header->terminateHandler; 944 + u_handler = old_exception_header->unexpectedHandler; 945 + // If std::__unexpected(u_handler) rethrows the same exception, 946 + // these values get overwritten by the rethrow. So save them now: 947 + ttypeIndex = old_exception_header->handlerSwitchValue; 948 + lsda = old_exception_header->languageSpecificData; 949 + } 950 + else 951 + { 952 + t_handler = std::get_terminate(); 953 + u_handler = std::get_unexpected(); 954 + } 955 + try 956 + { 957 + std::__unexpected(u_handler); 958 + } 959 + catch (...) 960 + { 961 + // If the old exception is foreign, then all we can do is terminate. 962 + // We have no way to recover the needed old exception spec. There's 963 + // no way to pass that information here. And the personality routine 964 + // can't call us directly and do anything but terminate() if we throw 965 + // from here. 966 + if (native_old_exception) 967 + { 968 + // Have: 969 + // old_exception_header->languageSpecificData 970 + // old_exception_header->actionRecord 971 + // Need 972 + // const uint8_t* classInfo 973 + // uint8_t ttypeEncoding 974 + uint8_t lpStartEncoding = *lsda++; 975 + const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); 976 + (void)lpStart; // purposefully unused. Just needed to increment lsda. 977 + uint8_t ttypeEncoding = *lsda++; 978 + if (ttypeEncoding == DW_EH_PE_omit) 979 + std::__terminate(t_handler); 980 + uintptr_t classInfoOffset = readULEB128(&lsda); 981 + const uint8_t* classInfo = lsda + classInfoOffset; 982 + // Is this new exception catchable by the exception spec at ttypeIndex? 983 + // The answer is obviously yes if the new and old exceptions are the same exception 984 + // If no 985 + // throw; 986 + __cxa_eh_globals* globals = __cxa_get_globals_fast(); 987 + __cxa_exception* new_exception_header = globals->caughtExceptions; 988 + if (new_exception_header == 0) 989 + // This shouldn't be able to happen! 990 + std::__terminate(t_handler); 991 + bool native_new_exception = 992 + (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) == 993 + (kOurExceptionClass & get_vendor_and_language); 994 + void* adjustedPtr; 995 + if (native_new_exception && (new_exception_header != old_exception_header)) 996 + { 997 + const __shim_type_info* excpType = 998 + static_cast<const __shim_type_info*>(new_exception_header->exceptionType); 999 + adjustedPtr = 1000 + new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ? 1001 + ((__cxa_dependent_exception*)new_exception_header)->primaryException : 1002 + new_exception_header + 1; 1003 + if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, 1004 + excpType, adjustedPtr, unwind_exception)) 1005 + { 1006 + // We need to __cxa_end_catch, but for the old exception, 1007 + // not the new one. This is a little tricky ... 1008 + // Disguise new_exception_header as a rethrown exception, but 1009 + // don't actually rethrow it. This means you can temporarily 1010 + // end the catch clause enclosing new_exception_header without 1011 + // __cxa_end_catch destroying new_exception_header. 1012 + new_exception_header->handlerCount = -new_exception_header->handlerCount; 1013 + globals->uncaughtExceptions += 1; 1014 + // Call __cxa_end_catch for new_exception_header 1015 + __cxa_end_catch(); 1016 + // Call __cxa_end_catch for old_exception_header 1017 + __cxa_end_catch(); 1018 + // Renter this catch clause with new_exception_header 1019 + __cxa_begin_catch(&new_exception_header->unwindHeader); 1020 + // Rethrow new_exception_header 1021 + throw; 1022 + } 1023 + } 1024 + // Will a std::bad_exception be catchable by the exception spec at 1025 + // ttypeIndex? 1026 + // If no 1027 + // throw std::bad_exception(); 1028 + const __shim_type_info* excpType = 1029 + static_cast<const __shim_type_info*>(&typeid(std::bad_exception)); 1030 + std::bad_exception be; 1031 + adjustedPtr = &be; 1032 + if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, 1033 + excpType, adjustedPtr, unwind_exception)) 1034 + { 1035 + // We need to __cxa_end_catch for both the old exception and the 1036 + // new exception. Technically we should do it in that order. 1037 + // But it is expedent to do it in the opposite order: 1038 + // Call __cxa_end_catch for new_exception_header 1039 + __cxa_end_catch(); 1040 + // Throw std::bad_exception will __cxa_end_catch for 1041 + // old_exception_header 1042 + throw be; 1043 + } 1044 + } 1045 + } 1046 + std::__terminate(t_handler); 1047 + } 1048 + 1049 + } // extern "C" 1050 + 1051 + } // __cxxabiv1
+27
src/libunwind-darwin-gcc/src-cxxabi/cxa_unexpected.cpp
··· 1 + //===------------------------- cxa_unexpected.cpp -------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include <exception> 11 + #include <cxxabi.h> 12 + #include "cxa_exception.hpp" 13 + 14 + namespace __cxxabiv1 15 + { 16 + 17 + #pragma GCC visibility push(default) 18 + 19 + extern "C" 20 + { 21 + 22 + } 23 + 24 + #pragma GCC visibility pop 25 + 26 + } // namespace __cxxabiv1 27 +
+367
src/libunwind-darwin-gcc/src-cxxabi/cxa_vector.cpp
··· 1 + //===-------------------------- cxa_vector.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Array Construction and Destruction APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi.html#array-ctor 11 + // 12 + //===----------------------------------------------------------------------===// 13 + 14 + #include "cxxabi.h" 15 + 16 + #include <exception> // for std::terminate 17 + 18 + namespace __cxxabiv1 { 19 + 20 + #pragma mark --Helper routines and classes -- 21 + 22 + namespace { 23 + inline static size_t __get_element_count ( void *p ) { 24 + return static_cast <size_t *> (p)[-1]; 25 + } 26 + 27 + inline static void __set_element_count ( void *p, size_t element_count ) { 28 + static_cast <size_t *> (p)[-1] = element_count; 29 + } 30 + 31 + 32 + // A pair of classes to simplify exception handling and control flow. 33 + // They get passed a block of memory in the constructor, and unless the 34 + // 'release' method is called, they deallocate the memory in the destructor. 35 + // Prefered usage is to allocate some memory, attach it to one of these objects, 36 + // and then, when all the operations to set up the memory block have succeeded, 37 + // call 'release'. If any of the setup operations fail, or an exception is 38 + // thrown, then the block is automatically deallocated. 39 + // 40 + // The only difference between these two classes is the signature for the 41 + // deallocation function (to match new2/new3 and delete2/delete3. 42 + class st_heap_block2 { 43 + public: 44 + typedef void (*dealloc_f)(void *); 45 + 46 + st_heap_block2 ( dealloc_f dealloc, void *ptr ) 47 + : dealloc_ ( dealloc ), ptr_ ( ptr ), enabled_ ( true ) {} 48 + ~st_heap_block2 () { if ( enabled_ ) dealloc_ ( ptr_ ) ; } 49 + void release () { enabled_ = false; } 50 + 51 + private: 52 + dealloc_f dealloc_; 53 + void *ptr_; 54 + bool enabled_; 55 + }; 56 + 57 + class st_heap_block3 { 58 + public: 59 + typedef void (*dealloc_f)(void *, size_t); 60 + 61 + st_heap_block3 ( dealloc_f dealloc, void *ptr, size_t size ) 62 + : dealloc_ ( dealloc ), ptr_ ( ptr ), size_ ( size ), enabled_ ( true ) {} 63 + ~st_heap_block3 () { if ( enabled_ ) dealloc_ ( ptr_, size_ ) ; } 64 + void release () { enabled_ = false; } 65 + 66 + private: 67 + dealloc_f dealloc_; 68 + void *ptr_; 69 + size_t size_; 70 + bool enabled_; 71 + }; 72 + 73 + class st_cxa_cleanup { 74 + public: 75 + typedef void (*destruct_f)(void *); 76 + 77 + st_cxa_cleanup ( void *ptr, size_t &idx, size_t element_size, destruct_f destructor ) 78 + : ptr_ ( ptr ), idx_ ( idx ), element_size_ ( element_size ), 79 + destructor_ ( destructor ), enabled_ ( true ) {} 80 + ~st_cxa_cleanup () { 81 + if ( enabled_ ) 82 + __cxa_vec_cleanup ( ptr_, idx_, element_size_, destructor_ ); 83 + } 84 + 85 + void release () { enabled_ = false; } 86 + 87 + private: 88 + void *ptr_; 89 + size_t &idx_; 90 + size_t element_size_; 91 + destruct_f destructor_; 92 + bool enabled_; 93 + }; 94 + 95 + class st_terminate { 96 + public: 97 + st_terminate ( bool enabled = true ) : enabled_ ( enabled ) {} 98 + ~st_terminate () { if ( enabled_ ) std::terminate (); } 99 + void release () { enabled_ = false; } 100 + private: 101 + bool enabled_ ; 102 + }; 103 + } 104 + 105 + #pragma mark --Externally visible routines-- 106 + 107 + extern "C" { 108 + 109 + // Equivalent to 110 + // 111 + // __cxa_vec_new2(element_count, element_size, padding_size, constructor, 112 + // destructor, &::operator new[], &::operator delete[]) 113 + void* __cxa_vec_new( 114 + size_t element_count, size_t element_size, size_t padding_size, 115 + void (*constructor)(void*), void (*destructor)(void*) ) { 116 + 117 + return __cxa_vec_new2 ( element_count, element_size, padding_size, 118 + constructor, destructor, &::operator new [], &::operator delete [] ); 119 + } 120 + 121 + 122 + 123 + // Given the number and size of elements for an array and the non-negative 124 + // size of prefix padding for a cookie, allocate space (using alloc) for 125 + // the array preceded by the specified padding, initialize the cookie if 126 + // the padding is non-zero, and call the given constructor on each element. 127 + // Return the address of the array proper, after the padding. 128 + // 129 + // If alloc throws an exception, rethrow the exception. If alloc returns 130 + // NULL, return NULL. If the constructor throws an exception, call 131 + // destructor for any already constructed elements, and rethrow the 132 + // exception. If the destructor throws an exception, call std::terminate. 133 + // 134 + // The constructor may be NULL, in which case it must not be called. If the 135 + // padding_size is zero, the destructor may be NULL; in that case it must 136 + // not be called. 137 + // 138 + // Neither alloc nor dealloc may be NULL. 139 + void* __cxa_vec_new2( 140 + size_t element_count, size_t element_size, size_t padding_size, 141 + void (*constructor)(void*), void (*destructor)(void*), 142 + void* (*alloc)(size_t), void (*dealloc)(void*) ) { 143 + 144 + const size_t heap_size = element_count * element_size + padding_size; 145 + char * const heap_block = static_cast<char *> ( alloc ( heap_size )); 146 + char *vec_base = heap_block; 147 + 148 + if ( NULL != vec_base ) { 149 + st_heap_block2 heap ( dealloc, heap_block ); 150 + 151 + // put the padding before the array elements 152 + if ( 0 != padding_size ) { 153 + vec_base += padding_size; 154 + __set_element_count ( vec_base, element_count ); 155 + } 156 + 157 + // Construct the elements 158 + __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor ); 159 + heap.release (); // We're good! 160 + } 161 + 162 + return vec_base; 163 + } 164 + 165 + 166 + // Same as __cxa_vec_new2 except that the deallocation function takes both 167 + // the object address and its size. 168 + void* __cxa_vec_new3( 169 + size_t element_count, size_t element_size, size_t padding_size, 170 + void (*constructor)(void*), void (*destructor)(void*), 171 + void* (*alloc)(size_t), void (*dealloc)(void*, size_t) ) { 172 + 173 + const size_t heap_size = element_count * element_size + padding_size; 174 + char * const heap_block = static_cast<char *> ( alloc ( heap_size )); 175 + char *vec_base = heap_block; 176 + 177 + if ( NULL != vec_base ) { 178 + st_heap_block3 heap ( dealloc, heap_block, heap_size ); 179 + 180 + // put the padding before the array elements 181 + if ( 0 != padding_size ) { 182 + vec_base += padding_size; 183 + __set_element_count ( vec_base, element_count ); 184 + } 185 + 186 + // Construct the elements 187 + __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor ); 188 + heap.release (); // We're good! 189 + } 190 + 191 + return vec_base; 192 + } 193 + 194 + 195 + // Given the (data) addresses of a destination and a source array, an 196 + // element count and an element size, call the given copy constructor to 197 + // copy each element from the source array to the destination array. The 198 + // copy constructor's arguments are the destination address and source 199 + // address, respectively. If an exception occurs, call the given destructor 200 + // (if non-NULL) on each copied element and rethrow. If the destructor 201 + // throws an exception, call terminate(). The constructor and or destructor 202 + // pointers may be NULL. If either is NULL, no action is taken when it 203 + // would have been called. 204 + 205 + void __cxa_vec_cctor( void* dest_array, void* src_array, 206 + size_t element_count, size_t element_size, 207 + void (*constructor) (void*, void*), void (*destructor)(void*) ) { 208 + 209 + if ( NULL != constructor ) { 210 + size_t idx = 0; 211 + char *src_ptr = static_cast<char *>(src_array); 212 + char *dest_ptr = static_cast<char *>(dest_array); 213 + st_cxa_cleanup cleanup ( dest_array, idx, element_size, destructor ); 214 + 215 + for ( idx = 0; idx < element_count; 216 + ++idx, src_ptr += element_size, dest_ptr += element_size ) 217 + constructor ( dest_ptr, src_ptr ); 218 + cleanup.release (); // We're good! 219 + } 220 + } 221 + 222 + 223 + // Given the (data) address of an array, not including any cookie padding, 224 + // and the number and size of its elements, call the given constructor on 225 + // each element. If the constructor throws an exception, call the given 226 + // destructor for any already-constructed elements, and rethrow the 227 + // exception. If the destructor throws an exception, call terminate(). The 228 + // constructor and/or destructor pointers may be NULL. If either is NULL, 229 + // no action is taken when it would have been called. 230 + void __cxa_vec_ctor( 231 + void* array_address, size_t element_count, size_t element_size, 232 + void (*constructor)(void*), void (*destructor)(void*) ) { 233 + 234 + if ( NULL != constructor ) { 235 + size_t idx; 236 + char *ptr = static_cast <char *> ( array_address ); 237 + st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor ); 238 + 239 + // Construct the elements 240 + for ( idx = 0; idx < element_count; ++idx, ptr += element_size ) 241 + constructor ( ptr ); 242 + cleanup.release (); // We're good! 243 + } 244 + } 245 + 246 + // Given the (data) address of an array, the number of elements, and the 247 + // size of its elements, call the given destructor on each element. If the 248 + // destructor throws an exception, rethrow after destroying the remaining 249 + // elements if possible. If the destructor throws a second exception, call 250 + // terminate(). The destructor pointer may be NULL, in which case this 251 + // routine does nothing. 252 + void __cxa_vec_dtor( 253 + void* array_address, size_t element_count, size_t element_size, 254 + void (*destructor)(void*) ) { 255 + 256 + if ( NULL != destructor ) { 257 + char *ptr = static_cast <char *> (array_address); 258 + size_t idx = element_count; 259 + st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor ); 260 + { 261 + st_terminate exception_guard (__cxa_uncaught_exception ()); 262 + ptr += element_count * element_size; // one past the last element 263 + 264 + while ( idx-- > 0 ) { 265 + ptr -= element_size; 266 + destructor ( ptr ); 267 + } 268 + exception_guard.release (); // We're good ! 269 + } 270 + cleanup.release (); // We're still good! 271 + } 272 + } 273 + 274 + // Given the (data) address of an array, the number of elements, and the 275 + // size of its elements, call the given destructor on each element. If the 276 + // destructor throws an exception, call terminate(). The destructor pointer 277 + // may be NULL, in which case this routine does nothing. 278 + void __cxa_vec_cleanup( void* array_address, size_t element_count, 279 + size_t element_size, void (*destructor)(void*) ) { 280 + 281 + if ( NULL != destructor ) { 282 + char *ptr = static_cast <char *> (array_address); 283 + size_t idx = element_count; 284 + st_terminate exception_guard; 285 + 286 + ptr += element_count * element_size; // one past the last element 287 + while ( idx-- > 0 ) { 288 + ptr -= element_size; 289 + destructor ( ptr ); 290 + } 291 + exception_guard.release (); // We're done! 292 + } 293 + } 294 + 295 + 296 + // If the array_address is NULL, return immediately. Otherwise, given the 297 + // (data) address of an array, the non-negative size of prefix padding for 298 + // the cookie, and the size of its elements, call the given destructor on 299 + // each element, using the cookie to determine the number of elements, and 300 + // then delete the space by calling ::operator delete[](void *). If the 301 + // destructor throws an exception, rethrow after (a) destroying the 302 + // remaining elements, and (b) deallocating the storage. If the destructor 303 + // throws a second exception, call terminate(). If padding_size is 0, the 304 + // destructor pointer must be NULL. If the destructor pointer is NULL, no 305 + // destructor call is to be made. 306 + // 307 + // The intent of this function is to permit an implementation to call this 308 + // function when confronted with an expression of the form delete[] p in 309 + // the source code, provided that the default deallocation function can be 310 + // used. Therefore, the semantics of this function are consistent with 311 + // those required by the standard. The requirement that the deallocation 312 + // function be called even if the destructor throws an exception derives 313 + // from the resolution to DR 353 to the C++ standard, which was adopted in 314 + // April, 2003. 315 + void __cxa_vec_delete( void* array_address, 316 + size_t element_size, size_t padding_size, void (*destructor)(void*) ) { 317 + 318 + __cxa_vec_delete2 ( array_address, element_size, padding_size, 319 + destructor, &::operator delete [] ); 320 + } 321 + 322 + 323 + // Same as __cxa_vec_delete, except that the given function is used for 324 + // deallocation instead of the default delete function. If dealloc throws 325 + // an exception, the result is undefined. The dealloc pointer may not be 326 + // NULL. 327 + void __cxa_vec_delete2( void* array_address, 328 + size_t element_size, size_t padding_size, 329 + void (*destructor)(void*), void (*dealloc)(void*) ) { 330 + 331 + if ( NULL != array_address ) { 332 + char *vec_base = static_cast <char *> (array_address); 333 + char *heap_block = vec_base - padding_size; 334 + st_heap_block2 heap ( dealloc, heap_block ); 335 + 336 + if ( 0 != padding_size && NULL != destructor ) // call the destructors 337 + __cxa_vec_dtor ( array_address, __get_element_count ( vec_base ), 338 + element_size, destructor ); 339 + } 340 + } 341 + 342 + 343 + // Same as __cxa_vec_delete, except that the given function is used for 344 + // deallocation instead of the default delete function. The deallocation 345 + // function takes both the object address and its size. If dealloc throws 346 + // an exception, the result is undefined. The dealloc pointer may not be 347 + // NULL. 348 + void __cxa_vec_delete3( void* array_address, 349 + size_t element_size, size_t padding_size, 350 + void (*destructor)(void*), void (*dealloc) (void*, size_t)) { 351 + 352 + if ( NULL != array_address ) { 353 + char *vec_base = static_cast <char *> (array_address); 354 + char *heap_block = vec_base - padding_size; 355 + const size_t element_count = padding_size ? __get_element_count ( vec_base ) : 0; 356 + const size_t heap_block_size = element_size * element_count + padding_size; 357 + st_heap_block3 heap ( dealloc, heap_block, heap_block_size ); 358 + 359 + if ( 0 != padding_size && NULL != destructor ) // call the destructors 360 + __cxa_vec_dtor ( array_address, element_count, element_size, destructor ); 361 + } 362 + } 363 + 364 + 365 + } // extern "C" 366 + 367 + } // abi
+31
src/libunwind-darwin-gcc/src-cxxabi/cxa_virtual.cpp
··· 1 + //===-------------------------- cxa_virtual.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include "cxxabi.h" 11 + #include "abort_message.h" 12 + 13 + namespace __cxxabiv1 14 + { 15 + 16 + extern "C" 17 + { 18 + 19 + LIBCXXABI_NORETURN 20 + void __cxa_pure_virtual(void) { 21 + abort_message("Pure virtual function called!"); 22 + } 23 + 24 + LIBCXXABI_NORETURN 25 + void __cxa_deleted_virtual(void) { 26 + abort_message("Deleted virtual function called!"); 27 + } 28 + 29 + } // extern "C" 30 + 31 + } // abi
+41
src/libunwind-darwin-gcc/src-cxxabi/exception.cpp
··· 1 + //===---------------------------- exception.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include <exception> 11 + 12 + #pragma GCC visibility push(default) 13 + 14 + namespace std 15 + { 16 + 17 + // exception 18 + 19 + exception::~exception() _NOEXCEPT 20 + { 21 + } 22 + 23 + const char* exception::what() const _NOEXCEPT 24 + { 25 + return "std::exception"; 26 + } 27 + 28 + // bad_exception 29 + 30 + bad_exception::~bad_exception() _NOEXCEPT 31 + { 32 + } 33 + 34 + const char* bad_exception::what() const _NOEXCEPT 35 + { 36 + return "std::bad_exception"; 37 + } 38 + 39 + } // std 40 + 41 + #pragma GCC visibility pop
+174
src/libunwind-darwin-gcc/src-cxxabi/fallback_malloc.ipp
··· 1 + //===------------------------ fallback_malloc.ipp -------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + // 9 + // This file implements the "Exception Handling APIs" 10 + // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 11 + // 12 + //===----------------------------------------------------------------------===// 13 + 14 + // A small, simple heap manager based (loosely) on 15 + // the startup heap manager from FreeBSD, optimized for space. 16 + // 17 + // Manages a fixed-size memory pool, supports malloc and free only. 18 + // No support for realloc. 19 + // 20 + // Allocates chunks in multiples of four bytes, with a four byte header 21 + // for each chunk. The overhead of each chunk is kept low by keeping pointers 22 + // as two byte offsets within the heap, rather than (4 or 8 byte) pointers. 23 + 24 + namespace { 25 + 26 + static pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER; 27 + 28 + class mutexor { 29 + public: 30 + mutexor ( pthread_mutex_t *m ) : mtx_(m) { pthread_mutex_lock ( mtx_ ); } 31 + ~mutexor () { pthread_mutex_unlock ( mtx_ ); } 32 + private: 33 + mutexor ( const mutexor &rhs ); 34 + mutexor & operator = ( const mutexor &rhs ); 35 + pthread_mutex_t *mtx_; 36 + }; 37 + 38 + 39 + #define HEAP_SIZE 512 40 + char heap [ HEAP_SIZE ]; 41 + 42 + typedef unsigned short heap_offset; 43 + typedef unsigned short heap_size; 44 + 45 + struct heap_node { 46 + heap_offset next_node; // offset into heap 47 + heap_size len; // size in units of "sizeof(heap_node)" 48 + }; 49 + 50 + static const heap_node *list_end = (heap_node *) ( &heap [ HEAP_SIZE ] ); // one past the end of the heap 51 + static heap_node *freelist = NULL; 52 + 53 + heap_node *node_from_offset ( const heap_offset offset ) 54 + { return (heap_node *) ( heap + ( offset * sizeof (heap_node))); } 55 + 56 + heap_offset offset_from_node ( const heap_node *ptr ) 57 + { return static_cast<heap_offset>(static_cast<size_t>(((char *) ptr ) - heap) / sizeof (heap_node)); } 58 + 59 + void init_heap () { 60 + freelist = (heap_node *) heap; 61 + freelist->next_node = offset_from_node ( list_end ); 62 + freelist->len = HEAP_SIZE / sizeof (heap_node); 63 + } 64 + 65 + // How big a chunk we allocate 66 + size_t alloc_size (size_t len) 67 + { return (len + sizeof(heap_node) - 1) / sizeof(heap_node) + 1; } 68 + 69 + bool is_fallback_ptr ( void *ptr ) 70 + { return ptr >= heap && ptr < ( heap + HEAP_SIZE ); } 71 + 72 + void *fallback_malloc(size_t len) { 73 + heap_node *p, *prev; 74 + const size_t nelems = alloc_size ( len ); 75 + mutexor mtx ( &heap_mutex ); 76 + 77 + if ( NULL == freelist ) 78 + init_heap (); 79 + 80 + // Walk the free list, looking for a "big enough" chunk 81 + for (p = freelist, prev = 0; 82 + p && p != list_end; prev = p, p = node_from_offset ( p->next_node)) { 83 + 84 + if (p->len > nelems) { // chunk is larger, shorten, and return the tail 85 + heap_node *q; 86 + 87 + p->len -= nelems; 88 + q = p + p->len; 89 + q->next_node = 0; 90 + q->len = static_cast<heap_size>(nelems); 91 + return (void *) (q + 1); 92 + } 93 + 94 + if (p->len == nelems) { // exact size match 95 + if (prev == 0) 96 + freelist = node_from_offset(p->next_node); 97 + else 98 + prev->next_node = p->next_node; 99 + p->next_node = 0; 100 + return (void *) (p + 1); 101 + } 102 + } 103 + return NULL; // couldn't find a spot big enough 104 + } 105 + 106 + // Return the start of the next block 107 + heap_node *after ( struct heap_node *p ) { return p + p->len; } 108 + 109 + void fallback_free (void *ptr) { 110 + struct heap_node *cp = ((struct heap_node *) ptr) - 1; // retrieve the chunk 111 + struct heap_node *p, *prev; 112 + 113 + mutexor mtx ( &heap_mutex ); 114 + 115 + #ifdef DEBUG_FALLBACK_MALLOC 116 + std::cout << "Freeing item at " << offset_from_node ( cp ) << " of size " << cp->len << std::endl; 117 + #endif 118 + 119 + for (p = freelist, prev = 0; 120 + p && p != list_end; prev = p, p = node_from_offset (p->next_node)) { 121 + #ifdef DEBUG_FALLBACK_MALLOC 122 + std::cout << " p, cp, after (p), after(cp) " 123 + << offset_from_node ( p ) << ' ' 124 + << offset_from_node ( cp ) << ' ' 125 + << offset_from_node ( after ( p )) << ' ' 126 + << offset_from_node ( after ( cp )) << std::endl; 127 + #endif 128 + if ( after ( p ) == cp ) { 129 + #ifdef DEBUG_FALLBACK_MALLOC 130 + std::cout << " Appending onto chunk at " << offset_from_node ( p ) << std::endl; 131 + #endif 132 + p->len += cp->len; // make the free heap_node larger 133 + return; 134 + } 135 + else if ( after ( cp ) == p ) { // there's a free heap_node right after 136 + #ifdef DEBUG_FALLBACK_MALLOC 137 + std::cout << " Appending free chunk at " << offset_from_node ( p ) << std::endl; 138 + #endif 139 + cp->len += p->len; 140 + if ( prev == 0 ) { 141 + freelist = cp; 142 + cp->next_node = p->next_node; 143 + } 144 + else 145 + prev->next_node = offset_from_node(cp); 146 + return; 147 + } 148 + } 149 + // Nothing to merge with, add it to the start of the free list 150 + #ifdef DEBUG_FALLBACK_MALLOC 151 + std::cout << " Making new free list entry " << offset_from_node ( cp ) << std::endl; 152 + #endif 153 + cp->next_node = offset_from_node ( freelist ); 154 + freelist = cp; 155 + } 156 + 157 + #ifdef INSTRUMENT_FALLBACK_MALLOC 158 + size_t print_free_list () { 159 + struct heap_node *p, *prev; 160 + heap_size total_free = 0; 161 + if ( NULL == freelist ) 162 + init_heap (); 163 + 164 + for (p = freelist, prev = 0; 165 + p && p != list_end; prev = p, p = node_from_offset (p->next_node)) { 166 + std::cout << ( prev == 0 ? "" : " ") << "Offset: " << offset_from_node ( p ) 167 + << "\tsize: " << p->len << " Next: " << p->next_node << std::endl; 168 + total_free += p->len; 169 + } 170 + std::cout << "Total Free space: " << total_free << std::endl; 171 + return total_free; 172 + } 173 + #endif 174 + } // end unnamed namespace
+1052
src/libunwind-darwin-gcc/src-cxxabi/private_typeinfo.cpp
··· 1 + //===----------------------- private_typeinfo.cpp -------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include "private_typeinfo.h" 11 + 12 + namespace __cxxabiv1 13 + { 14 + 15 + #pragma GCC visibility push(hidden) 16 + 17 + // __shim_type_info 18 + 19 + __shim_type_info::~__shim_type_info() 20 + { 21 + } 22 + 23 + void __shim_type_info::noop1() const {} 24 + void __shim_type_info::noop2() const {} 25 + 26 + // __fundamental_type_info 27 + 28 + // This miraculously (compiler magic) emits the type_info's for: 29 + // 1. all of the fundamental types 30 + // 2. pointers to all of the fundamental types 31 + // 3. pointers to all of the const fundamental types 32 + __fundamental_type_info::~__fundamental_type_info() 33 + { 34 + } 35 + 36 + // __array_type_info 37 + 38 + __array_type_info::~__array_type_info() 39 + { 40 + } 41 + 42 + // __function_type_info 43 + 44 + __function_type_info::~__function_type_info() 45 + { 46 + } 47 + 48 + // __enum_type_info 49 + 50 + __enum_type_info::~__enum_type_info() 51 + { 52 + } 53 + 54 + // __class_type_info 55 + 56 + __class_type_info::~__class_type_info() 57 + { 58 + } 59 + 60 + // __si_class_type_info 61 + 62 + __si_class_type_info::~__si_class_type_info() 63 + { 64 + } 65 + 66 + // __vmi_class_type_info 67 + 68 + __vmi_class_type_info::~__vmi_class_type_info() 69 + { 70 + } 71 + 72 + // __pbase_type_info 73 + 74 + __pbase_type_info::~__pbase_type_info() 75 + { 76 + } 77 + 78 + // __pointer_type_info 79 + 80 + __pointer_type_info::~__pointer_type_info() 81 + { 82 + } 83 + 84 + // __pointer_to_member_type_info 85 + 86 + __pointer_to_member_type_info::~__pointer_to_member_type_info() 87 + { 88 + } 89 + 90 + // can_catch 91 + 92 + // A handler is a match for an exception object of type E if 93 + // 1. The handler is of type cv T or cv T& and E and T are the same type 94 + // (ignoring the top-level cv-qualifiers), or 95 + // 2. the handler is of type cv T or cv T& and T is an unambiguous public 96 + // base class of E, or 97 + // 3. the handler is of type cv1 T* cv2 and E is a pointer type that can be 98 + // converted to the type of the handler by either or both of 99 + // A. a standard pointer conversion (4.10) not involving conversions to 100 + // pointers to private or protected or ambiguous classes 101 + // B. a qualification conversion 102 + // 4. the handler is a pointer or pointer to member type and E is 103 + // std::nullptr_t. 104 + 105 + // adjustedPtr: 106 + // 107 + // catch (A& a) : adjustedPtr == &a 108 + // catch (A* a) : adjustedPtr == a 109 + // catch (A** a) : adjustedPtr == a 110 + // 111 + // catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object) 112 + // catch (D2* d2) : adjustedPtr == d2 113 + // catch (D2*& d2) : adjustedPtr == d2 114 + // 115 + // catch (...) : adjustedPtr == & of the exception 116 + 117 + // Handles bullet 1 118 + bool 119 + __fundamental_type_info::can_catch(const __shim_type_info* thrown_type, 120 + void*&) const 121 + { 122 + return this == thrown_type; 123 + } 124 + 125 + bool 126 + __array_type_info::can_catch(const __shim_type_info*, void*&) const 127 + { 128 + // We can get here if someone tries to catch an array by reference. 129 + // However if someone tries to throw an array, it immediately gets 130 + // converted to a pointer, which will not convert back to an array 131 + // at the catch clause. So this can never catch anything. 132 + return false; 133 + } 134 + 135 + bool 136 + __function_type_info::can_catch(const __shim_type_info*, void*&) const 137 + { 138 + // We can get here if someone tries to catch a function by reference. 139 + // However if someone tries to throw a function, it immediately gets 140 + // converted to a pointer, which will not convert back to a function 141 + // at the catch clause. So this can never catch anything. 142 + return false; 143 + } 144 + 145 + // Handles bullet 1 146 + bool 147 + __enum_type_info::can_catch(const __shim_type_info* thrown_type, 148 + void*&) const 149 + { 150 + return this == thrown_type; 151 + } 152 + 153 + #pragma clang diagnostic push 154 + #pragma clang diagnostic ignored "-Wmissing-field-initializers" 155 + 156 + // Handles bullets 1 and 2 157 + bool 158 + __class_type_info::can_catch(const __shim_type_info* thrown_type, 159 + void*& adjustedPtr) const 160 + { 161 + // bullet 1 162 + if (this == thrown_type) 163 + return true; 164 + const __class_type_info* thrown_class_type = 165 + dynamic_cast<const __class_type_info*>(thrown_type); 166 + if (thrown_class_type == 0) 167 + return false; 168 + // bullet 2 169 + __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0}; 170 + info.number_of_dst_type = 1; 171 + thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 172 + if (info.path_dst_ptr_to_static_ptr == public_path) 173 + { 174 + adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 175 + return true; 176 + } 177 + return false; 178 + } 179 + 180 + #pragma clang diagnostic pop 181 + 182 + void 183 + __class_type_info::process_found_base_class(__dynamic_cast_info* info, 184 + void* adjustedPtr, 185 + int path_below) const 186 + { 187 + if (info->dst_ptr_leading_to_static_ptr == 0) 188 + { 189 + // First time here 190 + info->dst_ptr_leading_to_static_ptr = adjustedPtr; 191 + info->path_dst_ptr_to_static_ptr = path_below; 192 + info->number_to_static_ptr = 1; 193 + } 194 + else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr) 195 + { 196 + // We've been here before. Update path to "most public" 197 + if (info->path_dst_ptr_to_static_ptr == not_public_path) 198 + info->path_dst_ptr_to_static_ptr = path_below; 199 + } 200 + else 201 + { 202 + // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr) 203 + // to a static_type 204 + info->number_to_static_ptr += 1; 205 + info->path_dst_ptr_to_static_ptr = not_public_path; 206 + info->search_done = true; 207 + } 208 + } 209 + 210 + void 211 + __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 212 + void* adjustedPtr, 213 + int path_below) const 214 + { 215 + if (this == info->static_type) 216 + process_found_base_class(info, adjustedPtr, path_below); 217 + } 218 + 219 + void 220 + __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 221 + void* adjustedPtr, 222 + int path_below) const 223 + { 224 + if (this == info->static_type) 225 + process_found_base_class(info, adjustedPtr, path_below); 226 + else 227 + __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below); 228 + } 229 + 230 + void 231 + __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 232 + void* adjustedPtr, 233 + int path_below) const 234 + { 235 + ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 236 + if (__offset_flags & __virtual_mask) 237 + { 238 + const char* vtable = *static_cast<const char*const*>(adjustedPtr); 239 + offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 240 + } 241 + __base_type->has_unambiguous_public_base(info, 242 + static_cast<char*>(adjustedPtr) + offset_to_base, 243 + (__offset_flags & __public_mask) ? 244 + path_below : 245 + not_public_path); 246 + } 247 + 248 + void 249 + __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 250 + void* adjustedPtr, 251 + int path_below) const 252 + { 253 + if (this == info->static_type) 254 + process_found_base_class(info, adjustedPtr, path_below); 255 + else 256 + { 257 + typedef const __base_class_type_info* Iter; 258 + const Iter e = __base_info + __base_count; 259 + Iter p = __base_info; 260 + p->has_unambiguous_public_base(info, adjustedPtr, path_below); 261 + if (++p < e) 262 + { 263 + do 264 + { 265 + p->has_unambiguous_public_base(info, adjustedPtr, path_below); 266 + if (info->search_done) 267 + break; 268 + } while (++p < e); 269 + } 270 + } 271 + } 272 + 273 + // Handles bullets 1 and 4 for both pointers and member pointers 274 + bool 275 + __pbase_type_info::can_catch(const __shim_type_info* thrown_type, 276 + void*&) const 277 + { 278 + if (this == thrown_type) 279 + return true; 280 + return thrown_type == &typeid(std::nullptr_t); 281 + } 282 + 283 + #pragma clang diagnostic push 284 + #pragma clang diagnostic ignored "-Wmissing-field-initializers" 285 + 286 + // Handles bullets 1, 3 and 4 287 + bool 288 + __pointer_type_info::can_catch(const __shim_type_info* thrown_type, 289 + void*& adjustedPtr) const 290 + { 291 + // Do the dereference adjustment 292 + adjustedPtr = *static_cast<void**>(adjustedPtr); 293 + // bullets 1 and 4 294 + if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) 295 + return true; 296 + // bullet 3 297 + const __pointer_type_info* thrown_pointer_type = 298 + dynamic_cast<const __pointer_type_info*>(thrown_type); 299 + if (thrown_pointer_type == 0) 300 + return false; 301 + // bullet 3B 302 + if (thrown_pointer_type->__flags & ~__flags) 303 + return false; 304 + if (__pointee == thrown_pointer_type->__pointee) 305 + return true; 306 + // bullet 3A 307 + if (__pointee == &typeid(void)) 308 + return true; 309 + const __class_type_info* catch_class_type = 310 + dynamic_cast<const __class_type_info*>(__pointee); 311 + if (catch_class_type == 0) 312 + return false; 313 + const __class_type_info* thrown_class_type = 314 + dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee); 315 + if (thrown_class_type == 0) 316 + return false; 317 + __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0}; 318 + info.number_of_dst_type = 1; 319 + thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 320 + if (info.path_dst_ptr_to_static_ptr == public_path) 321 + { 322 + adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 323 + return true; 324 + } 325 + return false; 326 + } 327 + 328 + #pragma clang diagnostic pop 329 + 330 + #pragma GCC visibility pop 331 + #pragma GCC visibility push(default) 332 + 333 + #pragma clang diagnostic push 334 + #pragma clang diagnostic ignored "-Wmissing-field-initializers" 335 + 336 + // __dynamic_cast 337 + 338 + // static_ptr: pointer to an object of type static_type; nonnull, and since the 339 + // object is polymorphic, *(void**)static_ptr is a virtual table pointer. 340 + // static_ptr is &v in the expression dynamic_cast<T>(v). 341 + // static_type: static type of the object pointed to by static_ptr. 342 + // dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)"). 343 + // src2dst_offset: a static hint about the location of the 344 + // source subobject with respect to the complete object; 345 + // special negative values are: 346 + // -1: no hint 347 + // -2: static_type is not a public base of dst_type 348 + // -3: static_type is a multiple public base type but never a 349 + // virtual base type 350 + // otherwise, the static_type type is a unique public nonvirtual 351 + // base type of dst_type at offset src2dst_offset from the 352 + // origin of dst_type. 353 + // 354 + // (dynamic_ptr, dynamic_type) are the run time type of the complete object 355 + // referred to by static_ptr and a pointer to it. These can be found from 356 + // static_ptr for polymorphic types. 357 + // static_type is guaranteed to be a polymorphic type. 358 + // 359 + // (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward. Each 360 + // node of the tree represents a base class/object of its parent (or parents) below. 361 + // Each node is uniquely represented by a pointer to the object, and a pointer 362 + // to a type_info - its type. Different nodes may have the same pointer and 363 + // different nodes may have the same type. But only one node has a specific 364 + // (pointer-value, type) pair. In C++ two objects of the same type can not 365 + // share the same address. 366 + // 367 + // There are two flavors of nodes which have the type dst_type: 368 + // 1. Those that are derived from (below) (static_ptr, static_type). 369 + // 2. Those that are not derived from (below) (static_ptr, static_type). 370 + // 371 + // Invariants of the DAG: 372 + // 373 + // There is at least one path from the root (dynamic_ptr, dynamic_type) to 374 + // the node (static_ptr, static_type). This path may or may not be public. 375 + // There may be more than one such path (some public some not). Such a path may 376 + // or may not go through a node having type dst_type. 377 + // 378 + // No node of type T appears above a node of the same type. That means that 379 + // there is only one node with dynamic_type. And if dynamic_type == dst_type, 380 + // then there is only one dst_type in the DAG. 381 + // 382 + // No node of type dst_type appears above a node of type static_type. Such 383 + // DAG's are possible in C++, but the compiler computes those dynamic_casts at 384 + // compile time, and only calls __dynamic_cast when dst_type lies below 385 + // static_type in the DAG. 386 + // 387 + // dst_type != static_type: The compiler computes the dynamic_cast in this case too. 388 + // dynamic_type != static_type: The compiler computes the dynamic_cast in this case too. 389 + // 390 + // Returns: 391 + // 392 + // If there is exactly one dst_type of flavor 1, and 393 + // If there is a public path from that dst_type to (static_ptr, static_type), or 394 + // If there are 0 dst_types of flavor 2, and there is a public path from 395 + // (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public 396 + // path from (dynamic_ptr, dynamic_type) to the one dst_type, then return 397 + // a pointer to that dst_type. 398 + // Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and 399 + // if there is a public path from (dynamic_ptr, dynamic_type) to 400 + // (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type) 401 + // to the one dst_type, then return a pointer to that one dst_type. 402 + // Else return nullptr. 403 + // 404 + // If dynamic_type == dst_type, then the above algorithm collapses to the 405 + // following cheaper algorithm: 406 + // 407 + // If there is a public path from (dynamic_ptr, dynamic_type) to 408 + // (static_ptr, static_type), then return dynamic_ptr. 409 + // Else return nullptr. 410 + extern "C" 411 + void* 412 + __dynamic_cast(const void* static_ptr, 413 + const __class_type_info* static_type, 414 + const __class_type_info* dst_type, 415 + std::ptrdiff_t src2dst_offset) 416 + { 417 + // Possible future optimization: Take advantage of src2dst_offset 418 + // Currently clang always sets src2dst_offset to -1 (no hint). 419 + 420 + // Get (dynamic_ptr, dynamic_type) from static_ptr 421 + void** vtable = *(void***)static_ptr; 422 + ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]); 423 + const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived; 424 + const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]); 425 + 426 + // Initialize answer to nullptr. This will be changed from the search 427 + // results if a non-null answer is found. Regardless, this is what will 428 + // be returned. 429 + const void* dst_ptr = 0; 430 + // Initialize info struct for this search. 431 + __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; 432 + 433 + // Find out if we can use a giant short cut in the search 434 + if (dynamic_type == dst_type) 435 + { 436 + // Using giant short cut. Add that information to info. 437 + info.number_of_dst_type = 1; 438 + // Do the search 439 + dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path); 440 + // Query the search. 441 + if (info.path_dst_ptr_to_static_ptr == public_path) 442 + dst_ptr = dynamic_ptr; 443 + } 444 + else 445 + { 446 + // Not using giant short cut. Do the search 447 + dynamic_type->search_below_dst(&info, dynamic_ptr, public_path); 448 + // Query the search. 449 + switch (info.number_to_static_ptr) 450 + { 451 + case 0: 452 + if (info.number_to_dst_ptr == 1 && 453 + info.path_dynamic_ptr_to_static_ptr == public_path && 454 + info.path_dynamic_ptr_to_dst_ptr == public_path) 455 + dst_ptr = info.dst_ptr_not_leading_to_static_ptr; 456 + break; 457 + case 1: 458 + if (info.path_dst_ptr_to_static_ptr == public_path || 459 + ( 460 + info.number_to_dst_ptr == 0 && 461 + info.path_dynamic_ptr_to_static_ptr == public_path && 462 + info.path_dynamic_ptr_to_dst_ptr == public_path 463 + ) 464 + ) 465 + dst_ptr = info.dst_ptr_leading_to_static_ptr; 466 + break; 467 + } 468 + } 469 + return const_cast<void*>(dst_ptr); 470 + } 471 + 472 + #pragma clang diagnostic pop 473 + 474 + #pragma GCC visibility pop 475 + #pragma GCC visibility push(hidden) 476 + 477 + // Call this function when you hit a static_type which is a base (above) a dst_type. 478 + // Let caller know you hit a static_type. But only start recording details if 479 + // this is (static_ptr, static_type) -- the node we are casting from. 480 + // If this is (static_ptr, static_type) 481 + // Record the path (public or not) from the dst_type to here. There may be 482 + // multiple paths from the same dst_type to here, record the "most public" one. 483 + // Record the dst_ptr as pointing to (static_ptr, static_type). 484 + // If more than one (dst_ptr, dst_type) points to (static_ptr, static_type), 485 + // then mark this dyanmic_cast as ambiguous and stop the search. 486 + void 487 + __class_type_info::process_static_type_above_dst(__dynamic_cast_info* info, 488 + const void* dst_ptr, 489 + const void* current_ptr, 490 + int path_below) const 491 + { 492 + // Record that we found a static_type 493 + info->found_any_static_type = true; 494 + if (current_ptr == info->static_ptr) 495 + { 496 + // Record that we found (static_ptr, static_type) 497 + info->found_our_static_ptr = true; 498 + if (info->dst_ptr_leading_to_static_ptr == 0) 499 + { 500 + // First time here 501 + info->dst_ptr_leading_to_static_ptr = dst_ptr; 502 + info->path_dst_ptr_to_static_ptr = path_below; 503 + info->number_to_static_ptr = 1; 504 + // If there is only one dst_type in the entire tree and the path from 505 + // there to here is public then we are done! 506 + if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 507 + info->search_done = true; 508 + } 509 + else if (info->dst_ptr_leading_to_static_ptr == dst_ptr) 510 + { 511 + // We've been here before. Update path to "most public" 512 + if (info->path_dst_ptr_to_static_ptr == not_public_path) 513 + info->path_dst_ptr_to_static_ptr = path_below; 514 + // If there is only one dst_type in the entire tree and the path from 515 + // there to here is public then we are done! 516 + if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 517 + info->search_done = true; 518 + } 519 + else 520 + { 521 + // We've detected an ambiguous cast from (static_ptr, static_type) 522 + // to a dst_type 523 + info->number_to_static_ptr += 1; 524 + info->search_done = true; 525 + } 526 + } 527 + } 528 + 529 + // Call this function when you hit a static_type which is not a base (above) a dst_type. 530 + // If this is (static_ptr, static_type) 531 + // Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be 532 + // multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one. 533 + void 534 + __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, 535 + const void* current_ptr, 536 + int path_below) const 537 + { 538 + if (current_ptr == info->static_ptr) 539 + { 540 + // Record the most public path from (dynamic_ptr, dynamic_type) to 541 + // (static_ptr, static_type) 542 + if (info->path_dynamic_ptr_to_static_ptr != public_path) 543 + info->path_dynamic_ptr_to_static_ptr = path_below; 544 + } 545 + } 546 + 547 + // Call this function when searching below a dst_type node. This function searches 548 + // for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes. 549 + // If it finds a static_type node, there is no need to further search base classes 550 + // above. 551 + // If it finds a dst_type node it should search base classes using search_above_dst 552 + // to find out if this dst_type points to (static_ptr, static_type) or not. 553 + // Either way, the dst_type is recorded as one of two "flavors": one that does 554 + // or does not point to (static_ptr, static_type). 555 + // If this is neither a static_type nor a dst_type node, continue searching 556 + // base classes above. 557 + // All the hoopla surrounding the search code is doing nothing but looking for 558 + // excuses to stop the search prematurely (break out of the for-loop). That is, 559 + // the algorithm below is simply an optimization of this: 560 + // void 561 + // __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 562 + // const void* current_ptr, 563 + // int path_below) const 564 + // { 565 + // typedef const __base_class_type_info* Iter; 566 + // if (this == info->static_type) 567 + // process_static_type_below_dst(info, current_ptr, path_below); 568 + // else if (this == info->dst_type) 569 + // { 570 + // // Record the most public access path that got us here 571 + // if (info->path_dynamic_ptr_to_dst_ptr != public_path) 572 + // info->path_dynamic_ptr_to_dst_ptr = path_below; 573 + // bool does_dst_type_point_to_our_static_type = false; 574 + // for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p) 575 + // { 576 + // p->search_above_dst(info, current_ptr, current_ptr, public_path); 577 + // if (info->found_our_static_ptr) 578 + // does_dst_type_point_to_our_static_type = true; 579 + // // break out early here if you can detect it doesn't matter if you do 580 + // } 581 + // if (!does_dst_type_point_to_our_static_type) 582 + // { 583 + // // We found a dst_type that doesn't point to (static_ptr, static_type) 584 + // // So record the address of this dst_ptr and increment the 585 + // // count of the number of such dst_types found in the tree. 586 + // info->dst_ptr_not_leading_to_static_ptr = current_ptr; 587 + // info->number_to_dst_ptr += 1; 588 + // } 589 + // } 590 + // else 591 + // { 592 + // // This is not a static_type and not a dst_type. 593 + // for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 594 + // { 595 + // p->search_below_dst(info, current_ptr, public_path); 596 + // // break out early here if you can detect it doesn't matter if you do 597 + // } 598 + // } 599 + // } 600 + void 601 + __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 602 + const void* current_ptr, 603 + int path_below) const 604 + { 605 + typedef const __base_class_type_info* Iter; 606 + if (this == info->static_type) 607 + process_static_type_below_dst(info, current_ptr, path_below); 608 + else if (this == info->dst_type) 609 + { 610 + // We've been here before if we've recorded current_ptr in one of these 611 + // two places: 612 + if (current_ptr == info->dst_ptr_leading_to_static_ptr || 613 + current_ptr == info->dst_ptr_not_leading_to_static_ptr) 614 + { 615 + // We've seen this node before, and therefore have already searched 616 + // its base classes above. 617 + // Update path to here that is "most public". 618 + if (path_below == public_path) 619 + info->path_dynamic_ptr_to_dst_ptr = public_path; 620 + } 621 + else // We have haven't been here before 622 + { 623 + // Record the access path that got us here 624 + // If there is more than one dst_type this path doesn't matter. 625 + info->path_dynamic_ptr_to_dst_ptr = path_below; 626 + // Only search above here if dst_type derives from static_type, or 627 + // if it is unknown if dst_type derives from static_type. 628 + if (info->is_dst_type_derived_from_static_type != no) 629 + { 630 + // Set up flags to record results from all base classes 631 + bool is_dst_type_derived_from_static_type = false; 632 + bool does_dst_type_point_to_our_static_type = false; 633 + // We've found a dst_type with a potentially public path to here. 634 + // We have to assume the path is public because it may become 635 + // public later (if we get back to here with a public path). 636 + // We can stop looking above if: 637 + // 1. We've found a public path to (static_ptr, static_type). 638 + // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 639 + // This is detected at the (static_ptr, static_type). 640 + // 3. We can prove that there is no public path to (static_ptr, static_type) 641 + // above here. 642 + const Iter e = __base_info + __base_count; 643 + for (Iter p = __base_info; p < e; ++p) 644 + { 645 + // Zero out found flags 646 + info->found_our_static_ptr = false; 647 + info->found_any_static_type = false; 648 + p->search_above_dst(info, current_ptr, current_ptr, public_path); 649 + if (info->search_done) 650 + break; 651 + if (info->found_any_static_type) 652 + { 653 + is_dst_type_derived_from_static_type = true; 654 + if (info->found_our_static_ptr) 655 + { 656 + does_dst_type_point_to_our_static_type = true; 657 + // If we found what we're looking for, stop looking above. 658 + if (info->path_dst_ptr_to_static_ptr == public_path) 659 + break; 660 + // We found a private path to (static_ptr, static_type) 661 + // If there is no diamond then there is only one path 662 + // to (static_ptr, static_type) and we just found it. 663 + if (!(__flags & __diamond_shaped_mask)) 664 + break; 665 + } 666 + else 667 + { 668 + // If we found a static_type that isn't the one we're looking 669 + // for, and if there are no repeated types above here, 670 + // then stop looking. 671 + if (!(__flags & __non_diamond_repeat_mask)) 672 + break; 673 + } 674 + } 675 + } 676 + if (!does_dst_type_point_to_our_static_type) 677 + { 678 + // We found a dst_type that doesn't point to (static_ptr, static_type) 679 + // So record the address of this dst_ptr and increment the 680 + // count of the number of such dst_types found in the tree. 681 + info->dst_ptr_not_leading_to_static_ptr = current_ptr; 682 + info->number_to_dst_ptr += 1; 683 + // If there exists another dst with a private path to 684 + // (static_ptr, static_type), then the cast from 685 + // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, 686 + // so stop search. 687 + if (info->number_to_static_ptr == 1 && 688 + info->path_dst_ptr_to_static_ptr == not_public_path) 689 + info->search_done = true; 690 + } 691 + // If we found no static_type,s then dst_type doesn't derive 692 + // from static_type, else it does. Record this result so that 693 + // next time we hit a dst_type we will know not to search above 694 + // it if it doesn't derive from static_type. 695 + if (is_dst_type_derived_from_static_type) 696 + info->is_dst_type_derived_from_static_type = yes; 697 + else 698 + info->is_dst_type_derived_from_static_type = no; 699 + } 700 + } 701 + } 702 + else 703 + { 704 + // This is not a static_type and not a dst_type. 705 + const Iter e = __base_info + __base_count; 706 + Iter p = __base_info; 707 + p->search_below_dst(info, current_ptr, path_below); 708 + if (++p < e) 709 + { 710 + if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1) 711 + { 712 + // If there are multiple paths to a base above from here, or if 713 + // a dst_type pointing to (static_ptr, static_type) has been found, 714 + // then there is no way to break out of this loop early unless 715 + // something below detects the search is done. 716 + do 717 + { 718 + if (info->search_done) 719 + break; 720 + p->search_below_dst(info, current_ptr, path_below); 721 + } while (++p < e); 722 + } 723 + else if (__flags & __non_diamond_repeat_mask) 724 + { 725 + // There are not multiple paths to any base class from here and a 726 + // dst_type pointing to (static_ptr, static_type) has not yet been 727 + // found. 728 + do 729 + { 730 + if (info->search_done) 731 + break; 732 + // If we just found a dst_type with a public path to (static_ptr, static_type), 733 + // then the only reason to continue the search is to make sure 734 + // no other dst_type points to (static_ptr, static_type). 735 + // If !diamond, then we don't need to search here. 736 + if (info->number_to_static_ptr == 1 && 737 + info->path_dst_ptr_to_static_ptr == public_path) 738 + break; 739 + p->search_below_dst(info, current_ptr, path_below); 740 + } while (++p < e); 741 + } 742 + else 743 + { 744 + // There are no repeated types above this node. 745 + // There are no nodes with multiple parents above this node. 746 + // no dst_type has been found to (static_ptr, static_type) 747 + do 748 + { 749 + if (info->search_done) 750 + break; 751 + // If we just found a dst_type with a public path to (static_ptr, static_type), 752 + // then the only reason to continue the search is to make sure sure 753 + // no other dst_type points to (static_ptr, static_type). 754 + // If !diamond, then we don't need to search here. 755 + // if we just found a dst_type with a private path to (static_ptr, static_type), 756 + // then we're only looking for a public path to (static_ptr, static_type) 757 + // and to check for other dst_types. 758 + // If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type) 759 + // and not a dst_type under here. 760 + if (info->number_to_static_ptr == 1) 761 + break; 762 + p->search_below_dst(info, current_ptr, path_below); 763 + } while (++p < e); 764 + } 765 + } 766 + } 767 + } 768 + 769 + // This is the same algorithm as __vmi_class_type_info::search_below_dst but 770 + // simplified to the case that there is only a single base class. 771 + void 772 + __si_class_type_info::search_below_dst(__dynamic_cast_info* info, 773 + const void* current_ptr, 774 + int path_below) const 775 + { 776 + if (this == info->static_type) 777 + process_static_type_below_dst(info, current_ptr, path_below); 778 + else if (this == info->dst_type) 779 + { 780 + // We've been here before if we've recorded current_ptr in one of these 781 + // two places: 782 + if (current_ptr == info->dst_ptr_leading_to_static_ptr || 783 + current_ptr == info->dst_ptr_not_leading_to_static_ptr) 784 + { 785 + // We've seen this node before, and therefore have already searched 786 + // its base classes above. 787 + // Update path to here that is "most public". 788 + if (path_below == public_path) 789 + info->path_dynamic_ptr_to_dst_ptr = public_path; 790 + } 791 + else // We have haven't been here before 792 + { 793 + // Record the access path that got us here 794 + // If there is more than one dst_type this path doesn't matter. 795 + info->path_dynamic_ptr_to_dst_ptr = path_below; 796 + // Only search above here if dst_type derives from static_type, or 797 + // if it is unknown if dst_type derives from static_type. 798 + if (info->is_dst_type_derived_from_static_type != no) 799 + { 800 + // Set up flags to record results from all base classes 801 + bool is_dst_type_derived_from_static_type = false; 802 + bool does_dst_type_point_to_our_static_type = false; 803 + // Zero out found flags 804 + info->found_our_static_ptr = false; 805 + info->found_any_static_type = false; 806 + __base_type->search_above_dst(info, current_ptr, current_ptr, public_path); 807 + if (info->found_any_static_type) 808 + { 809 + is_dst_type_derived_from_static_type = true; 810 + if (info->found_our_static_ptr) 811 + does_dst_type_point_to_our_static_type = true; 812 + } 813 + if (!does_dst_type_point_to_our_static_type) 814 + { 815 + // We found a dst_type that doesn't point to (static_ptr, static_type) 816 + // So record the address of this dst_ptr and increment the 817 + // count of the number of such dst_types found in the tree. 818 + info->dst_ptr_not_leading_to_static_ptr = current_ptr; 819 + info->number_to_dst_ptr += 1; 820 + // If there exists another dst with a private path to 821 + // (static_ptr, static_type), then the cast from 822 + // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 823 + if (info->number_to_static_ptr == 1 && 824 + info->path_dst_ptr_to_static_ptr == not_public_path) 825 + info->search_done = true; 826 + } 827 + // If we found no static_type,s then dst_type doesn't derive 828 + // from static_type, else it does. Record this result so that 829 + // next time we hit a dst_type we will know not to search above 830 + // it if it doesn't derive from static_type. 831 + if (is_dst_type_derived_from_static_type) 832 + info->is_dst_type_derived_from_static_type = yes; 833 + else 834 + info->is_dst_type_derived_from_static_type = no; 835 + } 836 + } 837 + } 838 + else 839 + { 840 + // This is not a static_type and not a dst_type 841 + __base_type->search_below_dst(info, current_ptr, path_below); 842 + } 843 + } 844 + 845 + // This is the same algorithm as __vmi_class_type_info::search_below_dst but 846 + // simplified to the case that there is no base class. 847 + void 848 + __class_type_info::search_below_dst(__dynamic_cast_info* info, 849 + const void* current_ptr, 850 + int path_below) const 851 + { 852 + typedef const __base_class_type_info* Iter; 853 + if (this == info->static_type) 854 + process_static_type_below_dst(info, current_ptr, path_below); 855 + else if (this == info->dst_type) 856 + { 857 + // We've been here before if we've recorded current_ptr in one of these 858 + // two places: 859 + if (current_ptr == info->dst_ptr_leading_to_static_ptr || 860 + current_ptr == info->dst_ptr_not_leading_to_static_ptr) 861 + { 862 + // We've seen this node before, and therefore have already searched 863 + // its base classes above. 864 + // Update path to here that is "most public". 865 + if (path_below == public_path) 866 + info->path_dynamic_ptr_to_dst_ptr = public_path; 867 + } 868 + else // We have haven't been here before 869 + { 870 + // Record the access path that got us here 871 + // If there is more than one dst_type this path doesn't matter. 872 + info->path_dynamic_ptr_to_dst_ptr = path_below; 873 + // We found a dst_type that doesn't point to (static_ptr, static_type) 874 + // So record the address of this dst_ptr and increment the 875 + // count of the number of such dst_types found in the tree. 876 + info->dst_ptr_not_leading_to_static_ptr = current_ptr; 877 + info->number_to_dst_ptr += 1; 878 + // If there exists another dst with a private path to 879 + // (static_ptr, static_type), then the cast from 880 + // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 881 + if (info->number_to_static_ptr == 1 && 882 + info->path_dst_ptr_to_static_ptr == not_public_path) 883 + info->search_done = true; 884 + // We found that dst_type does not derive from static_type 885 + info->is_dst_type_derived_from_static_type = no; 886 + } 887 + } 888 + } 889 + 890 + // Call this function when searching above a dst_type node. This function searches 891 + // for a public path to (static_ptr, static_type). 892 + // This function is guaranteed not to find a node of type dst_type. 893 + // Theoretically this is a very simple function which just stops if it finds a 894 + // static_type node: All the hoopla surrounding the search code is doing 895 + // nothing but looking for excuses to stop the search prematurely (break out of 896 + // the for-loop). That is, the algorithm below is simply an optimization of this: 897 + // void 898 + // __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 899 + // const void* dst_ptr, 900 + // const void* current_ptr, 901 + // int path_below) const 902 + // { 903 + // if (this == info->static_type) 904 + // process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 905 + // else 906 + // { 907 + // typedef const __base_class_type_info* Iter; 908 + // // This is not a static_type and not a dst_type 909 + // for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 910 + // { 911 + // p->search_above_dst(info, dst_ptr, current_ptr, public_path); 912 + // // break out early here if you can detect it doesn't matter if you do 913 + // } 914 + // } 915 + // } 916 + void 917 + __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 918 + const void* dst_ptr, 919 + const void* current_ptr, 920 + int path_below) const 921 + { 922 + if (this == info->static_type) 923 + process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 924 + else 925 + { 926 + typedef const __base_class_type_info* Iter; 927 + // This is not a static_type and not a dst_type 928 + // Save flags so they can be restored when returning to nodes below. 929 + bool found_our_static_ptr = info->found_our_static_ptr; 930 + bool found_any_static_type = info->found_any_static_type; 931 + // We've found a dst_type below with a path to here. If the path 932 + // to here is not public, there may be another path to here that 933 + // is public. So we have to assume that the path to here is public. 934 + // We can stop looking above if: 935 + // 1. We've found a public path to (static_ptr, static_type). 936 + // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 937 + // This is detected at the (static_ptr, static_type). 938 + // 3. We can prove that there is no public path to (static_ptr, static_type) 939 + // above here. 940 + const Iter e = __base_info + __base_count; 941 + Iter p = __base_info; 942 + // Zero out found flags 943 + info->found_our_static_ptr = false; 944 + info->found_any_static_type = false; 945 + p->search_above_dst(info, dst_ptr, current_ptr, path_below); 946 + if (++p < e) 947 + { 948 + do 949 + { 950 + if (info->search_done) 951 + break; 952 + if (info->found_our_static_ptr) 953 + { 954 + // If we found what we're looking for, stop looking above. 955 + if (info->path_dst_ptr_to_static_ptr == public_path) 956 + break; 957 + // We found a private path to (static_ptr, static_type) 958 + // If there is no diamond then there is only one path 959 + // to (static_ptr, static_type) from here and we just found it. 960 + if (!(__flags & __diamond_shaped_mask)) 961 + break; 962 + } 963 + else if (info->found_any_static_type) 964 + { 965 + // If we found a static_type that isn't the one we're looking 966 + // for, and if there are no repeated types above here, 967 + // then stop looking. 968 + if (!(__flags & __non_diamond_repeat_mask)) 969 + break; 970 + } 971 + // Zero out found flags 972 + info->found_our_static_ptr = false; 973 + info->found_any_static_type = false; 974 + p->search_above_dst(info, dst_ptr, current_ptr, path_below); 975 + } while (++p < e); 976 + } 977 + // Restore flags 978 + info->found_our_static_ptr = found_our_static_ptr; 979 + info->found_any_static_type = found_any_static_type; 980 + } 981 + } 982 + 983 + // This is the same algorithm as __vmi_class_type_info::search_above_dst but 984 + // simplified to the case that there is only a single base class. 985 + void 986 + __si_class_type_info::search_above_dst(__dynamic_cast_info* info, 987 + const void* dst_ptr, 988 + const void* current_ptr, 989 + int path_below) const 990 + { 991 + if (this == info->static_type) 992 + process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 993 + else 994 + __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below); 995 + } 996 + 997 + // This is the same algorithm as __vmi_class_type_info::search_above_dst but 998 + // simplified to the case that there is no base class. 999 + void 1000 + __class_type_info::search_above_dst(__dynamic_cast_info* info, 1001 + const void* dst_ptr, 1002 + const void* current_ptr, 1003 + int path_below) const 1004 + { 1005 + if (this == info->static_type) 1006 + process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1007 + } 1008 + 1009 + // The search functions for __base_class_type_info are simply convenience 1010 + // functions for adjusting the current_ptr and path_below as the search is 1011 + // passed up to the base class node. 1012 + 1013 + void 1014 + __base_class_type_info::search_above_dst(__dynamic_cast_info* info, 1015 + const void* dst_ptr, 1016 + const void* current_ptr, 1017 + int path_below) const 1018 + { 1019 + ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 1020 + if (__offset_flags & __virtual_mask) 1021 + { 1022 + const char* vtable = *static_cast<const char*const*>(current_ptr); 1023 + offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 1024 + } 1025 + __base_type->search_above_dst(info, dst_ptr, 1026 + static_cast<const char*>(current_ptr) + offset_to_base, 1027 + (__offset_flags & __public_mask) ? 1028 + path_below : 1029 + not_public_path); 1030 + } 1031 + 1032 + void 1033 + __base_class_type_info::search_below_dst(__dynamic_cast_info* info, 1034 + const void* current_ptr, 1035 + int path_below) const 1036 + { 1037 + ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 1038 + if (__offset_flags & __virtual_mask) 1039 + { 1040 + const char* vtable = *static_cast<const char*const*>(current_ptr); 1041 + offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 1042 + } 1043 + __base_type->search_below_dst(info, 1044 + static_cast<const char*>(current_ptr) + offset_to_base, 1045 + (__offset_flags & __public_mask) ? 1046 + path_below : 1047 + not_public_path); 1048 + } 1049 + 1050 + #pragma GCC visibility pop 1051 + 1052 + } // __cxxabiv1
+248
src/libunwind-darwin-gcc/src-cxxabi/private_typeinfo.h
··· 1 + //===------------------------ private_typeinfo.h --------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #ifndef __PRIVATE_TYPEINFO_H_ 11 + #define __PRIVATE_TYPEINFO_H_ 12 + 13 + #include <typeinfo> 14 + #include <cstddef> 15 + 16 + namespace __cxxabiv1 17 + { 18 + 19 + #pragma GCC visibility push(hidden) 20 + 21 + class __attribute__ ((__visibility__("hidden"))) __shim_type_info 22 + : public std::type_info 23 + { 24 + public: 25 + virtual ~__shim_type_info(); 26 + 27 + virtual void noop1() const; 28 + virtual void noop2() const; 29 + virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const = 0; 30 + }; 31 + 32 + class __attribute__ ((__visibility__("default"))) __fundamental_type_info 33 + : public __shim_type_info 34 + { 35 + public: 36 + __attribute__ ((__visibility__("hidden"))) virtual ~__fundamental_type_info(); 37 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 38 + }; 39 + 40 + class __attribute__ ((__visibility__("default"))) __array_type_info 41 + : public __shim_type_info 42 + { 43 + public: 44 + __attribute__ ((__visibility__("hidden"))) virtual ~__array_type_info(); 45 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 46 + }; 47 + 48 + class __attribute__ ((__visibility__("default"))) __function_type_info 49 + : public __shim_type_info 50 + { 51 + public: 52 + __attribute__ ((__visibility__("hidden"))) virtual ~__function_type_info(); 53 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 54 + }; 55 + 56 + class __attribute__ ((__visibility__("default"))) __enum_type_info 57 + : public __shim_type_info 58 + { 59 + public: 60 + __attribute__ ((__visibility__("hidden"))) virtual ~__enum_type_info(); 61 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 62 + }; 63 + 64 + enum 65 + { 66 + unknown = 0, 67 + public_path, 68 + not_public_path, 69 + yes, 70 + no 71 + }; 72 + 73 + class __attribute__ ((__visibility__("default"))) __class_type_info; 74 + 75 + struct __dynamic_cast_info 76 + { 77 + // const data supplied to the search: 78 + 79 + const __class_type_info* const dst_type; 80 + const void* const static_ptr; 81 + const __class_type_info* const static_type; 82 + const std::ptrdiff_t src2dst_offset; 83 + 84 + // Data that represents the answer: 85 + 86 + // pointer to a dst_type which has (static_ptr, static_type) above it 87 + const void* dst_ptr_leading_to_static_ptr; 88 + // pointer to a dst_type which does not have (static_ptr, static_type) above it 89 + const void* dst_ptr_not_leading_to_static_ptr; 90 + 91 + // The following three paths are either unknown, public_path or not_public_path. 92 + // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type) 93 + int path_dst_ptr_to_static_ptr; 94 + // access of path from (dynamic_ptr, dynamic_type) to (static_ptr, static_type) 95 + // when there is no dst_type along the path 96 + int path_dynamic_ptr_to_static_ptr; 97 + // access of path from (dynamic_ptr, dynamic_type) to dst_type 98 + // (not used if there is a (static_ptr, static_type) above a dst_type). 99 + int path_dynamic_ptr_to_dst_ptr; 100 + 101 + // Number of dst_types below (static_ptr, static_type) 102 + int number_to_static_ptr; 103 + // Number of dst_types not below (static_ptr, static_type) 104 + int number_to_dst_ptr; 105 + 106 + // Data that helps stop the search before the entire tree is searched: 107 + 108 + // is_dst_type_derived_from_static_type is either unknown, yes or no. 109 + int is_dst_type_derived_from_static_type; 110 + // Number of dst_type in tree. If 0, then that means unknown. 111 + int number_of_dst_type; 112 + // communicates to a dst_type node that (static_ptr, static_type) was found 113 + // above it. 114 + bool found_our_static_ptr; 115 + // communicates to a dst_type node that a static_type was found 116 + // above it, but it wasn't (static_ptr, static_type) 117 + bool found_any_static_type; 118 + // Set whenever a search can be stopped 119 + bool search_done; 120 + }; 121 + 122 + // Has no base class 123 + class __attribute__ ((__visibility__("default"))) __class_type_info 124 + : public __shim_type_info 125 + { 126 + public: 127 + __attribute__ ((__visibility__("hidden"))) virtual ~__class_type_info(); 128 + 129 + __attribute__ ((__visibility__("hidden"))) 130 + void process_static_type_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; 131 + __attribute__ ((__visibility__("hidden"))) 132 + void process_static_type_below_dst(__dynamic_cast_info*, const void*, int) const; 133 + __attribute__ ((__visibility__("hidden"))) 134 + void process_found_base_class(__dynamic_cast_info*, void*, int) const; 135 + __attribute__ ((__visibility__("hidden"))) 136 + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; 137 + __attribute__ ((__visibility__("hidden"))) 138 + virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; 139 + __attribute__ ((__visibility__("hidden"))) 140 + virtual bool can_catch(const __shim_type_info*, void*&) const; 141 + __attribute__ ((__visibility__("hidden"))) 142 + virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; 143 + }; 144 + 145 + // Has one non-virtual public base class at offset zero 146 + class __attribute__ ((__visibility__("default"))) __si_class_type_info 147 + : public __class_type_info 148 + { 149 + public: 150 + const __class_type_info* __base_type; 151 + 152 + __attribute__ ((__visibility__("hidden"))) virtual ~__si_class_type_info(); 153 + 154 + __attribute__ ((__visibility__("hidden"))) 155 + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; 156 + __attribute__ ((__visibility__("hidden"))) 157 + virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; 158 + __attribute__ ((__visibility__("hidden"))) 159 + virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; 160 + }; 161 + 162 + struct __base_class_type_info 163 + { 164 + public: 165 + const __class_type_info* __base_type; 166 + long __offset_flags; 167 + 168 + enum __offset_flags_masks 169 + { 170 + __virtual_mask = 0x1, 171 + __public_mask = 0x2, // base is public 172 + __offset_shift = 8 173 + }; 174 + 175 + void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; 176 + void search_below_dst(__dynamic_cast_info*, const void*, int) const; 177 + void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; 178 + }; 179 + 180 + // Has one or more base classes 181 + class __attribute__ ((__visibility__("default"))) __vmi_class_type_info 182 + : public __class_type_info 183 + { 184 + public: 185 + unsigned int __flags; 186 + unsigned int __base_count; 187 + __base_class_type_info __base_info[1]; 188 + 189 + enum __flags_masks 190 + { 191 + __non_diamond_repeat_mask = 0x1, // has two or more distinct base class 192 + // objects of the same type 193 + __diamond_shaped_mask = 0x2 // has base class object with two or 194 + // more derived objects 195 + }; 196 + 197 + __attribute__ ((__visibility__("hidden"))) virtual ~__vmi_class_type_info(); 198 + 199 + __attribute__ ((__visibility__("hidden"))) 200 + virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const; 201 + __attribute__ ((__visibility__("hidden"))) 202 + virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const; 203 + __attribute__ ((__visibility__("hidden"))) 204 + virtual void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; 205 + }; 206 + 207 + class __attribute__ ((__visibility__("default"))) __pbase_type_info 208 + : public __shim_type_info 209 + { 210 + public: 211 + unsigned int __flags; 212 + const __shim_type_info* __pointee; 213 + 214 + enum __masks 215 + { 216 + __const_mask = 0x1, 217 + __volatile_mask = 0x2, 218 + __restrict_mask = 0x4, 219 + __incomplete_mask = 0x8, 220 + __incomplete_class_mask = 0x10 221 + }; 222 + 223 + __attribute__ ((__visibility__("hidden"))) virtual ~__pbase_type_info(); 224 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 225 + }; 226 + 227 + class __attribute__ ((__visibility__("default"))) __pointer_type_info 228 + : public __pbase_type_info 229 + { 230 + public: 231 + __attribute__ ((__visibility__("hidden"))) virtual ~__pointer_type_info(); 232 + __attribute__ ((__visibility__("hidden"))) virtual bool can_catch(const __shim_type_info*, void*&) const; 233 + }; 234 + 235 + class __attribute__ ((__visibility__("default"))) __pointer_to_member_type_info 236 + : public __pbase_type_info 237 + { 238 + public: 239 + const __class_type_info* __context; 240 + 241 + __attribute__ ((__visibility__("hidden"))) virtual ~__pointer_to_member_type_info(); 242 + }; 243 + 244 + #pragma GCC visibility pop 245 + 246 + } // __cxxabiv1 247 + 248 + #endif // __PRIVATE_TYPEINFO_H_
+122
src/libunwind-darwin-gcc/src-cxxabi/stdexcept.cpp
··· 1 + //===------------------------ stdexcept.cpp -------------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include "stdexcept" 11 + #include "new" 12 + #include <cstdlib> 13 + #include <cstring> 14 + #include <cstdint> 15 + #include <cstddef> 16 + 17 + // Note: optimize for size 18 + 19 + #pragma GCC visibility push(hidden) 20 + 21 + namespace 22 + { 23 + 24 + class __libcpp_nmstr 25 + { 26 + private: 27 + const char* str_; 28 + 29 + typedef std::size_t unused_t; 30 + typedef std::ptrdiff_t count_t; 31 + 32 + static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(2*sizeof(unused_t) + 33 + sizeof(count_t)); 34 + 35 + count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} 36 + public: 37 + explicit __libcpp_nmstr(const char* msg); 38 + __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 39 + __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW; 40 + ~__libcpp_nmstr() _LIBCPP_CANTTHROW; 41 + const char* c_str() const _NOEXCEPT {return str_;} 42 + }; 43 + 44 + __libcpp_nmstr::__libcpp_nmstr(const char* msg) 45 + { 46 + std::size_t len = strlen(msg); 47 + str_ = new char[len + 1 + offset]; 48 + unused_t* c = (unused_t*)str_; 49 + c[0] = c[1] = len; 50 + str_ += offset; 51 + count() = 0; 52 + std::strcpy(const_cast<char*>(c_str()), msg); 53 + } 54 + 55 + inline 56 + __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) 57 + : str_(s.str_) 58 + { 59 + __sync_add_and_fetch(&count(), 1); 60 + } 61 + 62 + __libcpp_nmstr& 63 + __libcpp_nmstr::operator=(const __libcpp_nmstr& s) 64 + { 65 + const char* p = str_; 66 + str_ = s.str_; 67 + __sync_add_and_fetch(&count(), 1); 68 + if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0) 69 + delete [] (p-offset); 70 + return *this; 71 + } 72 + 73 + inline 74 + __libcpp_nmstr::~__libcpp_nmstr() 75 + { 76 + if (__sync_add_and_fetch(&count(), count_t(-1)) < 0) 77 + delete [] (str_ - offset); 78 + } 79 + 80 + } 81 + 82 + #pragma GCC visibility pop 83 + 84 + namespace std // purposefully not using versioning namespace 85 + { 86 + 87 + logic_error::~logic_error() _NOEXCEPT 88 + { 89 + __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 90 + s.~__libcpp_nmstr(); 91 + } 92 + 93 + const char* 94 + logic_error::what() const _NOEXCEPT 95 + { 96 + __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 97 + return s.c_str(); 98 + } 99 + 100 + runtime_error::~runtime_error() _NOEXCEPT 101 + { 102 + __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 103 + s.~__libcpp_nmstr(); 104 + } 105 + 106 + const char* 107 + runtime_error::what() const _NOEXCEPT 108 + { 109 + __libcpp_nmstr& s = (__libcpp_nmstr&)__imp_; 110 + return s.c_str(); 111 + } 112 + 113 + domain_error::~domain_error() _NOEXCEPT {} 114 + invalid_argument::~invalid_argument() _NOEXCEPT {} 115 + length_error::~length_error() _NOEXCEPT {} 116 + out_of_range::~out_of_range() _NOEXCEPT {} 117 + 118 + range_error::~range_error() _NOEXCEPT {} 119 + overflow_error::~overflow_error() _NOEXCEPT {} 120 + underflow_error::~underflow_error() _NOEXCEPT {} 121 + 122 + } // std
+53
src/libunwind-darwin-gcc/src-cxxabi/typeinfo.cpp
··· 1 + //===----------------------------- typeinfo.cpp ---------------------------===// 2 + // 3 + // The LLVM Compiler Infrastructure 4 + // 5 + // This file is dual licensed under the MIT and the University of Illinois Open 6 + // Source Licenses. See LICENSE.TXT for details. 7 + // 8 + //===----------------------------------------------------------------------===// 9 + 10 + #include <typeinfo> 11 + 12 + namespace std 13 + { 14 + 15 + // type_info 16 + 17 + type_info::~type_info() 18 + { 19 + } 20 + 21 + // bad_cast 22 + 23 + bad_cast::bad_cast() _NOEXCEPT 24 + { 25 + } 26 + 27 + bad_cast::~bad_cast() _NOEXCEPT 28 + { 29 + } 30 + 31 + const char* 32 + bad_cast::what() const _NOEXCEPT 33 + { 34 + return "std::bad_cast"; 35 + } 36 + 37 + // bad_typeid 38 + 39 + bad_typeid::bad_typeid() _NOEXCEPT 40 + { 41 + } 42 + 43 + bad_typeid::~bad_typeid() _NOEXCEPT 44 + { 45 + } 46 + 47 + const char* 48 + bad_typeid::what() const _NOEXCEPT 49 + { 50 + return "std::bad_typeid"; 51 + } 52 + 53 + } // std
+155
src/libunwind-darwin-gcc/src-unwind/darwin-crt2.c
··· 1 + /* KeyMgr backwards-compatibility support for Darwin. 2 + Copyright (C) 2001, 2002, 2004, 2009 Free Software Foundation, Inc. 3 + 4 + This file is part of GCC. 5 + 6 + GCC is free software; you can redistribute it and/or modify it under 7 + the terms of the GNU General Public License as published by the Free 8 + Software Foundation; either version 3, or (at your option) any later 9 + version. 10 + 11 + GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 + WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 + for more details. 15 + 16 + Under Section 7 of GPL version 3, you are granted additional 17 + permissions described in the GCC Runtime Library Exception, version 18 + 3.1, as published by the Free Software Foundation. 19 + 20 + You should have received a copy of the GNU General Public License and 21 + a copy of the GCC Runtime Library Exception along with this program; 22 + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 + <http://www.gnu.org/licenses/>. */ 24 + 25 + /* It is incorrect to include config.h here, because this file is being 26 + compiled for the target, and hence definitions concerning only the host 27 + do not apply. */ 28 + 29 + #include "tconfig.h" 30 + #include "tsystem.h" 31 + 32 + /* This file doesn't do anything useful on non-powerpc targets, since they 33 + don't have backwards compatibility anyway. */ 34 + 35 + //#ifdef __ppc__ 36 + 37 + /* Homemade decls substituting for getsect.h and dyld.h, so cross 38 + compilation works. */ 39 + struct mach_header; 40 + extern char *getsectdatafromheader (struct mach_header *, const char *, 41 + const char *, unsigned long *); 42 + extern void _dyld_register_func_for_add_image 43 + (void (*) (struct mach_header *, unsigned long)); 44 + extern void _dyld_register_func_for_remove_image 45 + (void (*) (struct mach_header *, unsigned long)); 46 + 47 + __attribute__((constructor)) 48 + static void __darwin_gcc3_preregister_frame_info (void); 49 + 50 + /* These are from "keymgr.h". */ 51 + // extern void _init_keymgr (void); 52 + extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key); 53 + extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr); 54 + 55 + //extern void *__keymgr_global[]; 56 + typedef struct _Sinfo_Node { 57 + unsigned int size ; /*size of this node*/ 58 + unsigned short major_version ; /*API major version.*/ 59 + unsigned short minor_version ; /*API minor version.*/ 60 + } _Tinfo_Node ; 61 + 62 + /* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */ 63 + #define KEYMGR_API_MAJOR_GCC3 3 64 + /* ... with these keys. */ 65 + #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 66 + #define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 67 + 68 + /* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */ 69 + struct live_images { 70 + unsigned long this_size; /* sizeof (live_images) */ 71 + struct mach_header *mh; /* the image info */ 72 + unsigned long vm_slide; 73 + void (*destructor)(struct live_images *); /* destructor for this */ 74 + struct live_images *next; 75 + unsigned int examined_p; 76 + void *fde; 77 + void *object_info; 78 + unsigned long info[2]; /* Future use. */ 79 + }; 80 + 81 + 82 + /* These routines are used only on Darwin versions before 10.2. 83 + Later versions have equivalent code in the system. 84 + Eventually, they might go away, although it might be a long time... */ 85 + 86 + static void darwin_unwind_dyld_remove_image_hook 87 + (struct mach_header *m, unsigned long s); 88 + static void darwin_unwind_dyld_remove_image_hook 89 + (struct mach_header *m, unsigned long s); 90 + extern void __darwin_gcc3_preregister_frame_info (void); 91 + 92 + static void 93 + darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide) 94 + { 95 + struct live_images *l = (struct live_images *)calloc (1, sizeof (*l)); 96 + l->mh = mh; 97 + l->vm_slide = slide; 98 + l->this_size = sizeof (*l); 99 + l->next = (struct live_images *) 100 + _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 101 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l); 102 + } 103 + 104 + static void 105 + darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s) 106 + { 107 + struct live_images *top, **lip, *destroy = NULL; 108 + 109 + /* Look for it in the list of live images and delete it. */ 110 + 111 + top = (struct live_images *) 112 + _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 113 + for (lip = &top; *lip != NULL; lip = &(*lip)->next) 114 + { 115 + if ((*lip)->mh == m && (*lip)->vm_slide == s) 116 + { 117 + destroy = *lip; 118 + *lip = destroy->next; /* unlink DESTROY */ 119 + 120 + if (destroy->this_size != sizeof (*destroy)) /* sanity check */ 121 + abort (); 122 + 123 + break; 124 + } 125 + } 126 + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top); 127 + 128 + /* Now that we have unlinked this from the image list, toss it. */ 129 + if (destroy != NULL) 130 + { 131 + if (destroy->destructor != NULL) 132 + (*destroy->destructor) (destroy); 133 + free (destroy); 134 + } 135 + } 136 + 137 + void 138 + __darwin_gcc3_preregister_frame_info (void) 139 + { 140 + #if 0 141 + const _Tinfo_Node *info; 142 + _init_keymgr (); 143 + info = (_Tinfo_Node *)__keymgr_global[2]; 144 + if (info != NULL) 145 + { 146 + if (info->major_version >= KEYMGR_API_MAJOR_GCC3) 147 + return; 148 + /* Otherwise, use our own add_image_hooks. */ 149 + } 150 + #endif 151 + _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook); 152 + _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook); 153 + } 154 + 155 + // #endif /* __ppc__ */
src/libunwind-darwin-gcc/tconfig.h src/libunwind-darwin-gcc/src-unwind/tconfig.h
src/libunwind-darwin-gcc/tm.h src/libunwind-darwin-gcc/src-unwind/tm.h
src/libunwind-darwin-gcc/tsystem.h src/libunwind-darwin-gcc/src-unwind/tsystem.h
+1 -1
src/libunwind-darwin-gcc/unwind-c.c src/libunwind-darwin-gcc/src-unwind/unwind-c.c
··· 26 26 27 27 #include "tconfig.h" 28 28 #include "tsystem.h" 29 - #include "unwind.h" 29 + #include "unwind-generic.h" 30 30 #define NO_SIZE_OF_ENCODED_VALUE 31 31 #include "unwind-pe.h" 32 32
+1 -1
src/libunwind-darwin-gcc/unwind-compat.c src/libunwind-darwin-gcc/src-unwind/unwind-compat.c
··· 26 26 #if defined (USE_GAS_SYMVER) && defined (USE_LIBUNWIND_EXCEPTIONS) 27 27 #include "tconfig.h" 28 28 #include "tsystem.h" 29 - #include "unwind.h" 29 + #include "unwind-generic.h" 30 30 #include "unwind-dw2-fde.h" 31 31 #include "unwind-compat.h" 32 32
src/libunwind-darwin-gcc/unwind-compat.h src/libunwind-darwin-gcc/src-unwind/unwind-compat.h
+1 -1
src/libunwind-darwin-gcc/unwind-dw2-fde-compat.c src/libunwind-darwin-gcc/src-unwind/unwind-dw2-fde-compat.c
··· 26 26 #if defined (USE_GAS_SYMVER) && defined (USE_LIBUNWIND_EXCEPTIONS) 27 27 #include "tconfig.h" 28 28 #include "tsystem.h" 29 - #include "unwind.h" 29 + #include "unwind-generic.h" 30 30 #include "unwind-dw2-fde.h" 31 31 #include "unwind-compat.h" 32 32
+1 -1
src/libunwind-darwin-gcc/unwind-dw2-fde-darwin.c src/libunwind-darwin-gcc/src-unwind/unwind-dw2-fde-darwin.c
··· 29 29 #include <string.h> 30 30 #include <stdlib.h> 31 31 #include "dwarf2.h" 32 - #include "unwind.h" 32 + #include "unwind-generic.h" 33 33 #define NO_BASE_OF_ENCODED_VALUE 34 34 #define DWARF2_OBJECT_END_PTR_EXTENSION 35 35 #include "unwind-pe.h"
+1 -1
src/libunwind-darwin-gcc/unwind-dw2-fde.c src/libunwind-darwin-gcc/src-unwind/unwind-dw2-fde.c
··· 30 30 #include "coretypes.h" 31 31 #include "tm.h" 32 32 #include "dwarf2.h" 33 - #include "unwind.h" 33 + #include "unwind-generic.h" 34 34 #define NO_BASE_OF_ENCODED_VALUE 35 35 #include "unwind-pe.h" 36 36 #include "unwind-dw2-fde.h"
src/libunwind-darwin-gcc/unwind-dw2-fde.h src/libunwind-darwin-gcc/src-unwind/unwind-dw2-fde.h
+1 -1
src/libunwind-darwin-gcc/unwind-dw2.c src/libunwind-darwin-gcc/src-unwind/unwind-dw2.c
··· 28 28 #include "coretypes.h" 29 29 #include "tm.h" 30 30 #include "dwarf2.h" 31 - #include "unwind.h" 31 + #include "unwind-generic.h" 32 32 #ifdef __USING_SJLJ_EXCEPTIONS__ 33 33 # define NO_SIZE_OF_ENCODED_VALUE 34 34 #endif
src/libunwind-darwin-gcc/unwind-dw2.h src/libunwind-darwin-gcc/src-unwind/unwind-dw2.h
+7 -7
src/libunwind-darwin-gcc/unwind-generic.h src/libunwind-darwin-gcc/src-unwind/unwind-generic.h
··· 25 25 /* This is derived from the C++ ABI for IA-64. Where we diverge 26 26 for cross-architecture compatibility are noted with "@@@". */ 27 27 28 - #ifndef _UNWIND_H 29 - #define _UNWIND_H 28 + #ifndef _UNWIND_HX 29 + #define _UNWIND_HX 30 30 31 31 #ifndef HIDE_EXPORTS 32 32 #pragma GCC visibility push(default) ··· 45 45 #if defined(__ia64__) && defined(__hpux__) 46 46 typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); 47 47 #else 48 - typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); 48 + typedef unsigned long _Unwind_Ptr /*__attribute__((__mode__(__pointer__)))*/; 49 49 #endif 50 - typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); 50 + typedef unsigned long _Unwind_Internal_Ptr /*__attribute__((__mode__(__pointer__)))*/; 51 51 52 52 /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and 53 53 consumer of an exception. We'll go along with this for now even on 54 54 32-bit machines. We'll need to provide some other option for 55 55 16-bit machines and for machines with > 8 bits per byte. */ 56 - typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); 56 + typedef unsigned long long _Unwind_Exception_Class /*__attribute__((__mode__(__DI__)))*/; 57 57 58 58 /* The unwind interface uses reason codes in several contexts to 59 59 identify the reasons for failures or other actions. */ 60 - #ifndef __clang__ 60 + 61 61 typedef enum 62 62 { 63 63 _URC_NO_REASON = 0, ··· 70 70 _URC_INSTALL_CONTEXT = 7, 71 71 _URC_CONTINUE_UNWIND = 8 72 72 } _Unwind_Reason_Code; 73 - #endif 73 + 74 74 75 75 /* The unwind interface uses a pointer to an exception header object 76 76 as its representation of an exception being thrown. In general, the
src/libunwind-darwin-gcc/unwind-pe.h src/libunwind-darwin-gcc/src-unwind/unwind-pe.h
+1 -1
src/libunwind-darwin-gcc/unwind-sjlj.c src/libunwind-darwin-gcc/src-unwind/unwind-sjlj.c
··· 27 27 #include "tsystem.h" 28 28 #include "coretypes.h" 29 29 #include "tm.h" 30 - #include "unwind.h" 30 + //#include "unwind.h" 31 31 #include "gthr.h" 32 32 33 33 #ifdef __USING_SJLJ_EXCEPTIONS__
src/libunwind-darwin-gcc/unwind.inc src/libunwind-darwin-gcc/src-unwind/unwind.inc