ReactOS 0.4.16-dev-303-g11d5cb8
cpp.c
Go to the documentation of this file.
1/*
2 * msvcrt.dll C++ objects
3 *
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2003, 2004 Alexandre Julliard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdbool.h>
24
25#include "windef.h"
26#include "winternl.h"
27#include "wine/exception.h"
28#include "wine/debug.h"
29#include "msvcrt.h"
30#include "mtdll.h"
31#include "cxx.h"
32
34
37
39{
40 void *memPtr;
42};
43
44typedef exception bad_cast;
45typedef exception bad_typeid;
46typedef exception __non_rtti_object;
47
48extern const vtable_ptr bad_typeid_vtable;
49extern const vtable_ptr bad_cast_vtable;
51extern const vtable_ptr type_info_vtable;
52
53/* get the vtable pointer for a C++ object */
54static inline const vtable_ptr *get_vtable( void *obj )
55{
56 return *(const vtable_ptr **)obj;
57}
58
59static inline const rtti_object_locator *get_obj_locator( void *cppobj )
60{
61 const vtable_ptr *vtable = get_vtable( cppobj );
62 return (const rtti_object_locator *)vtable[-1];
63}
64
65#ifndef __x86_64__
67{
68 int i;
69 const rtti_object_hierarchy *h = ptr->type_hierarchy;
70
71 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
72 ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
73 ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy );
74 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
75 h->signature, h->attributes, h->array_len, h->base_classes );
76 for (i = 0; i < h->array_len; i++)
77 {
78 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
79 h->base_classes->bases[i],
80 h->base_classes->bases[i]->num_base_classes,
81 h->base_classes->bases[i]->offsets.this_offset,
82 h->base_classes->bases[i]->offsets.vbase_descr,
83 h->base_classes->bases[i]->offsets.vbase_offset,
84 h->base_classes->bases[i]->attributes,
85 h->base_classes->bases[i]->type_descriptor,
86 dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) );
87 }
88}
89
90#else
91
92static void dump_obj_locator( const rtti_object_locator *ptr )
93{
94 int i;
95 char *base = ptr->signature == 0 ? RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator;
96 const rtti_object_hierarchy *h = (const rtti_object_hierarchy*)(base + ptr->type_hierarchy);
97 const type_info *type_descriptor = (const type_info*)(base + ptr->type_descriptor);
98
99 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
100 ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
101 type_descriptor, dbgstr_type_info(type_descriptor), h );
102 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
103 h->signature, h->attributes, h->array_len, base + h->base_classes );
104 for (i = 0; i < h->array_len; i++)
105 {
107 ((const rtti_base_array*)(base + h->base_classes))->bases[i]);
108
109 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
110 bases,
111 bases->num_base_classes,
112 bases->offsets.this_offset,
113 bases->offsets.vbase_descr,
114 bases->offsets.vbase_offset,
115 bases->attributes,
116 base + bases->type_descriptor,
117 dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) );
118 }
119}
120#endif
121
122#ifdef __REACTOS__
123#include <internal/wine_msc.h>
124#endif /* __REACTOS__ */
125
126/******************************************************************
127 * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
128 */
131{
132 TRACE("(%p,%s)\n", _this, *name);
133 return __exception_ctor(_this, *name, &exception_vtable);
134}
135
136/******************************************************************
137 * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
138 */
141{
142 TRACE("(%p,%s)\n", _this, *name);
143 _this->vtable = &exception_vtable;
144 _this->name = *name;
145 _this->do_free = FALSE;
146 return _this;
147}
148
149/******************************************************************
150 * ??0exception@@QAE@XZ (MSVCRT.@)
151 */
154{
155 TRACE("(%p)\n", _this);
156 return __exception_ctor(_this, NULL, &exception_vtable);
157}
158
159/******************************************************************
160 * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
161 */
164{
165 TRACE("(%p %p)\n", _this, rhs);
166 if (_this != rhs)
167 {
168 exception_dtor(_this);
169 exception_copy_ctor(_this, rhs);
170 }
171 TRACE("name = %s\n", _this->name);
172 return _this;
173}
174
175/******************************************************************
176 * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
177 */
180{
181 TRACE("(%p %x)\n", _this, flags);
182 exception_dtor(_this);
183 if (flags & 1) operator_delete(_this);
184 return _this;
185}
186
187/******************************************************************
188 * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
189 */
191bad_typeid * __thiscall bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
192{
193 TRACE("(%p %p)\n", _this, rhs);
194 return __exception_copy_ctor(_this, rhs, &bad_typeid_vtable);
195}
196
197/******************************************************************
198 * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
199 */
201bad_typeid * __thiscall bad_typeid_ctor(bad_typeid * _this, const char * name)
202{
203 TRACE("(%p %s)\n", _this, name);
204 return __exception_ctor(_this, name, &bad_typeid_vtable);
205}
206
207/******************************************************************
208 * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
209 */
211bad_typeid * __thiscall bad_typeid_default_ctor(bad_typeid * _this)
212{
213 return bad_typeid_ctor( _this, "bad typeid" );
214}
215
216/******************************************************************
217 * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
218 */
220void __thiscall bad_typeid_dtor(bad_typeid * _this)
221{
222 TRACE("(%p)\n", _this);
223 exception_dtor(_this);
224}
225
226/******************************************************************
227 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
228 */
230bad_typeid * __thiscall bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
231{
232 TRACE("(%p %p)\n", _this, rhs);
233 exception_opequals(_this, rhs);
234 return _this;
235}
236
237/******************************************************************
238 * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
239 */
241void * __thiscall bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags)
242{
243 TRACE("(%p %x)\n", _this, flags);
244 if (flags & 2)
245 {
246 /* we have an array, with the number of elements stored before the first object */
247 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
248
249 for (i = *ptr - 1; i >= 0; i--) bad_typeid_dtor(_this + i);
251 }
252 else
253 {
254 bad_typeid_dtor(_this);
255 if (flags & 1) operator_delete(_this);
256 }
257 return _this;
258}
259
260/******************************************************************
261 * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
262 */
264void * __thiscall bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags)
265{
266 TRACE("(%p %x)\n", _this, flags);
267 bad_typeid_dtor(_this);
268 if (flags & 1) operator_delete(_this);
269 return _this;
270}
271
272/******************************************************************
273 * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
274 */
276__non_rtti_object * __thiscall __non_rtti_object_copy_ctor(__non_rtti_object * _this,
277 const __non_rtti_object * rhs)
278{
279 TRACE("(%p %p)\n", _this, rhs);
280 return __exception_copy_ctor(_this, rhs, &__non_rtti_object_vtable);
281}
282
283/******************************************************************
284 * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
285 */
287__non_rtti_object * __thiscall __non_rtti_object_ctor(__non_rtti_object * _this,
288 const char * name)
289{
290 TRACE("(%p %s)\n", _this, name);
291 return __exception_ctor(_this, name, &__non_rtti_object_vtable);
292}
293
294/******************************************************************
295 * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
296 */
298void __thiscall __non_rtti_object_dtor(__non_rtti_object * _this)
299{
300 TRACE("(%p)\n", _this);
301 bad_typeid_dtor(_this);
302}
303
304/******************************************************************
305 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
306 */
308__non_rtti_object * __thiscall __non_rtti_object_opequals(__non_rtti_object * _this,
309 const __non_rtti_object *rhs)
310{
311 TRACE("(%p %p)\n", _this, rhs);
312 bad_typeid_opequals(_this, rhs);
313 return _this;
314}
315
316/******************************************************************
317 * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
318 */
320void * __thiscall __non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags)
321{
322 TRACE("(%p %x)\n", _this, flags);
323 if (flags & 2)
324 {
325 /* we have an array, with the number of elements stored before the first object */
326 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
327
328 for (i = *ptr - 1; i >= 0; i--) __non_rtti_object_dtor(_this + i);
330 }
331 else
332 {
334 if (flags & 1) operator_delete(_this);
335 }
336 return _this;
337}
338
339/******************************************************************
340 * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
341 */
343void * __thiscall __non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags)
344{
345 TRACE("(%p %x)\n", _this, flags);
347 if (flags & 1) operator_delete(_this);
348 return _this;
349}
350
351/******************************************************************
352 * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
353 * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
354 */
356bad_cast * __thiscall bad_cast_ctor(bad_cast * _this, const char ** name)
357{
358 TRACE("(%p %s)\n", _this, *name);
359 return __exception_ctor(_this, *name, &bad_cast_vtable);
360}
361
362/******************************************************************
363 * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
364 */
366bad_cast * __thiscall bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs)
367{
368 TRACE("(%p %p)\n", _this, rhs);
369 return __exception_copy_ctor(_this, rhs, &bad_cast_vtable);
370}
371
372/******************************************************************
373 * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
374 */
376bad_cast * __thiscall bad_cast_ctor_charptr(bad_cast * _this, const char * name)
377{
378 TRACE("(%p %s)\n", _this, name);
379 return __exception_ctor(_this, name, &bad_cast_vtable);
380}
381
382/******************************************************************
383 * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
384 */
386bad_cast * __thiscall bad_cast_default_ctor(bad_cast * _this)
387{
388 return bad_cast_ctor_charptr( _this, "bad cast" );
389}
390
391/******************************************************************
392 * ??1bad_cast@@UAE@XZ (MSVCRT.@)
393 */
396{
397 TRACE("(%p)\n", _this);
398 exception_dtor(_this);
399}
400
401/******************************************************************
402 * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
403 */
405bad_cast * __thiscall bad_cast_opequals(bad_cast * _this, const bad_cast * rhs)
406{
407 TRACE("(%p %p)\n", _this, rhs);
408 exception_opequals(_this, rhs);
409 return _this;
410}
411
412/******************************************************************
413 * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
414 */
416void * __thiscall bad_cast_vector_dtor(bad_cast * _this, unsigned int flags)
417{
418 TRACE("(%p %x)\n", _this, flags);
419 if (flags & 2)
420 {
421 /* we have an array, with the number of elements stored before the first object */
422 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
423
424 for (i = *ptr - 1; i >= 0; i--) bad_cast_dtor(_this + i);
426 }
427 else
428 {
429 bad_cast_dtor(_this);
430 if (flags & 1) operator_delete(_this);
431 }
432 return _this;
433}
434
435/******************************************************************
436 * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
437 */
439void * __thiscall bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags)
440{
441 TRACE("(%p %x)\n", _this, flags);
442 bad_cast_dtor(_this);
443 if (flags & 1) operator_delete(_this);
444 return _this;
445}
446
447/******************************************************************
448 * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
449 */
452{
453 int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1);
454 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
455 return ret;
456}
457
458/******************************************************************
459 * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
460 */
463{
464 int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1);
465 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
466 return ret;
467}
468
469/******************************************************************
470 * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
471 */
474{
475 int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0;
476 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
477 return ret;
478}
479
480/******************************************************************
481 * ??1type_info@@UAE@XZ (MSVCRT.@)
482 */
485{
486 TRACE("(%p)\n", _this);
487 free(_this->name);
488}
489
490/******************************************************************
491 * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
492 */
495{
496 if (!_this->name)
497 {
498 /* Create and set the demangled name */
499 /* Note: mangled name in type_info struct always starts with a '.', while
500 * it isn't valid for mangled name.
501 * Is this '.' really part of the mangled name, or has it some other meaning ?
502 */
503 char* name = __unDName(0, _this->mangled + 1, 0,
505 if (name)
506 {
507 unsigned int len = strlen(name);
508
509 /* It seems _unDName may leave blanks at the end of the demangled name */
510 while (len && name[--len] == ' ')
511 name[len] = '\0';
512
513 if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
514 {
515 /* Another thread set this member since we checked above - use it */
516 free(name);
517 }
518 }
519 }
520 TRACE("(%p) returning %s\n", _this, _this->name);
521 return _this->name;
522}
523
524/******************************************************************
525 * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
526 */
529{
530 TRACE("(%p) returning %s\n", _this, _this->mangled);
531 return _this->mangled;
532}
533
534#if _MSVCR_VER >= 80
535
536typedef exception bad_alloc;
537extern const vtable_ptr bad_alloc_vtable;
538
539/* bad_alloc class implementation */
540DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor,8)
541bad_alloc * __thiscall bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs)
542{
543 TRACE("(%p %p)\n", _this, rhs);
544 return __exception_copy_ctor(_this, rhs, &bad_alloc_vtable);
545}
546
547DEFINE_THISCALL_WRAPPER(bad_alloc_dtor,4)
548void __thiscall bad_alloc_dtor(bad_alloc * _this)
549{
550 TRACE("(%p)\n", _this);
551 exception_dtor(_this);
552}
553
554#endif /* _MSVCR_VER >= 80 */
555
556__ASM_BLOCK_BEGIN(vtables)
557
558#if _MSVCR_VER >= 80
559__ASM_VTABLE(exception_old,
562__ASM_VTABLE(bad_alloc,
565#endif
566__ASM_VTABLE(bad_typeid,
572__ASM_VTABLE(__non_rtti_object,
575
577
578#if _MSVCR_VER >= 80
579DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" )
580DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" )
581DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" )
582DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" )
583DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" )
584#else
585DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" )
586DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" )
587DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" )
588#endif
589
590DEFINE_CXX_EXCEPTION0( exception, exception_dtor )
591DEFINE_CXX_DATA1( bad_typeid, &exception_cxx_type_info, bad_typeid_dtor )
592DEFINE_CXX_DATA1( bad_cast, &exception_cxx_type_info, bad_cast_dtor )
593DEFINE_CXX_DATA2( __non_rtti_object, &bad_typeid_cxx_type_info,
594 &exception_cxx_type_info, __non_rtti_object_dtor )
595#if _MSVCR_VER >= 80
596DEFINE_CXX_DATA1( bad_alloc, &exception_cxx_type_info, bad_alloc_dtor )
597#endif
598
599void msvcrt_init_exception(void *base)
600{
601#ifdef __x86_64__
602 init_type_info_rtti(base);
603 init_exception_rtti(base);
604#if _MSVCR_VER >= 80
605 init_exception_old_rtti(base);
606 init_bad_alloc_rtti(base);
607#endif
608 init_bad_typeid_rtti(base);
609 init_bad_cast_rtti(base);
610 init___non_rtti_object_rtti(base);
611
612 init_exception_cxx(base);
613 init_bad_typeid_cxx(base);
614 init_bad_cast_cxx(base);
615 init___non_rtti_object_cxx(base);
616#if _MSVCR_VER >= 80
617 init_bad_alloc_cxx(base);
618#endif
619#endif
620}
621
622#if _MSVCR_VER >= 80
623void throw_bad_alloc(void)
624{
625 bad_alloc e;
626 __exception_ctor(&e, "bad allocation", &bad_alloc_vtable);
627 _CxxThrowException(&e, &bad_alloc_exception_type);
628}
629#endif
630
631/******************************************************************
632 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
633 *
634 * Install a handler to be called when terminate() is called.
635 *
636 * PARAMS
637 * func [I] Handler function to install
638 *
639 * RETURNS
640 * The previously installed handler function, if any.
641 */
643{
645 terminate_function previous = data->terminate_handler;
646 TRACE("(%p) returning %p\n",func,previous);
647 data->terminate_handler = func;
648 return previous;
649}
650
651/******************************************************************
652 * _get_terminate (MSVCRT.@)
653 */
655{
657 TRACE("returning %p\n", data->terminate_handler);
658 return data->terminate_handler;
659}
660
661/******************************************************************
662 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
663 *
664 * Install a handler to be called when unexpected() is called.
665 *
666 * PARAMS
667 * func [I] Handler function to install
668 *
669 * RETURNS
670 * The previously installed handler function, if any.
671 */
673{
675 unexpected_function previous = data->unexpected_handler;
676 TRACE("(%p) returning %p\n",func,previous);
677 data->unexpected_handler = func;
678 return previous;
679}
680
681/******************************************************************
682 * _get_unexpected (MSVCRT.@)
683 */
685{
687 TRACE("returning %p\n", data->unexpected_handler);
688 return data->unexpected_handler;
689}
690
691/******************************************************************
692 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
693 */
695{
697 _se_translator_function previous = data->se_translator;
698 TRACE("(%p) returning %p\n",func,previous);
699 data->se_translator = func;
700 return previous;
701}
702
703/******************************************************************
704 * ?terminate@@YAXXZ (MSVCRT.@)
705 *
706 * Default handler for an unhandled exception.
707 *
708 * PARAMS
709 * None.
710 *
711 * RETURNS
712 * This function does not return. Either control resumes from any
713 * handler installed by calling set_terminate(), or (by default) abort()
714 * is called.
715 */
716void CDECL terminate(void)
717{
719 if (data->terminate_handler) data->terminate_handler();
720 abort();
721}
722
723/******************************************************************
724 * ?unexpected@@YAXXZ (MSVCRT.@)
725 */
727{
729 if (data->unexpected_handler) data->unexpected_handler();
730 terminate();
731}
732
733
734/******************************************************************
735 * __RTtypeid (MSVCRT.@)
736 *
737 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
738 *
739 * PARAMS
740 * cppobj [I] C++ object to get type information for.
741 *
742 * RETURNS
743 * Success: A type_info object describing cppobj.
744 * Failure: If the object to be cast has no RTTI, a __non_rtti_object
745 * exception is thrown. If cppobj is NULL, a bad_typeid exception
746 * is thrown. In either case, this function does not return.
747 *
748 * NOTES
749 * This function is usually called by compiler generated code as a result
750 * of using one of the C++ dynamic cast statements.
751 */
752#ifndef __x86_64__
753const type_info* CDECL __RTtypeid(void *cppobj)
754{
755 const type_info *ret;
756
757 if (!cppobj)
758 {
759 bad_typeid e;
760 bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
761 _CxxThrowException( &e, &bad_typeid_exception_type );
762 }
763
764 __TRY
765 {
766 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
767 ret = obj_locator->type_descriptor;
768 }
770 {
771 __non_rtti_object e;
772 __non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
773 _CxxThrowException( &e, &__non_rtti_object_exception_type );
774 }
776 return ret;
777}
778
779#else
780
781const type_info* CDECL __RTtypeid(void *cppobj)
782{
783 const type_info *ret;
784
785 if (!cppobj)
786 {
787 bad_typeid e;
788 bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
789 _CxxThrowException( &e, &bad_typeid_exception_type );
790 }
791
792 __TRY
793 {
794 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
795 char *base;
796
797 if(obj_locator->signature == 0)
798 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
799 else
800 base = (char*)obj_locator - obj_locator->object_locator;
801
802 ret = (type_info*)(base + obj_locator->type_descriptor);
803 }
805 {
806 __non_rtti_object e;
807 __non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
808 _CxxThrowException( &e, &__non_rtti_object_exception_type );
809 }
811 return ret;
812}
813#endif
814
815/******************************************************************
816 * __RTDynamicCast (MSVCRT.@)
817 *
818 * Dynamically cast a C++ object to one of its base classes.
819 *
820 * PARAMS
821 * cppobj [I] Any C++ object to cast
822 * unknown [I] Reserved, set to 0
823 * src [I] type_info object describing cppobj
824 * dst [I] type_info object describing the base class to cast to
825 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
826 *
827 * RETURNS
828 * Success: The address of cppobj, cast to the object described by dst.
829 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
830 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
831 * is thrown and this function does not return.
832 *
833 * NOTES
834 * This function is usually called by compiler generated code as a result
835 * of using one of the C++ dynamic cast statements.
836 */
837#ifndef __x86_64__
838void* CDECL __RTDynamicCast(void *cppobj, int unknown,
840 int do_throw)
841{
842 void *ret;
843
844 if (!cppobj) return NULL;
845
846 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
847 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
848
849 /* To cast an object at runtime:
850 * 1.Find out the true type of the object from the typeinfo at vtable[-1]
851 * 2.Search for the destination type in the class hierarchy
852 * 3.If destination type is found, return base object address + dest offset
853 * Otherwise, fail the cast
854 *
855 * FIXME: the unknown parameter doesn't seem to be used for anything
856 */
857 __TRY
858 {
859 int i;
860 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
861 const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
862 const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;
863
864 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
865
866 ret = NULL;
867 for (i = 0; i < obj_bases->array_len; i++)
868 {
869 const type_info *typ = base_desc[i]->type_descriptor;
870
871 if (!strcmp(typ->mangled, dst->mangled))
872 {
873 /* compute the correct this pointer for that base class */
874 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
875 ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
876 break;
877 }
878 }
879 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
880 * to a reference, since references cannot be NULL.
881 */
882 if (!ret && do_throw)
883 {
884 const char *msg = "Bad dynamic_cast!";
885 bad_cast e;
886 bad_cast_ctor( &e, &msg );
887 _CxxThrowException( &e, &bad_cast_exception_type );
888 }
889 }
891 {
892 __non_rtti_object e;
893 __non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
894 _CxxThrowException( &e, &__non_rtti_object_exception_type );
895 }
897 return ret;
898}
899
900#else
901
902void* CDECL __RTDynamicCast(void *cppobj, int unknown,
904 int do_throw)
905{
906 void *ret;
907
908 if (!cppobj) return NULL;
909
910 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
911 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
912
913 __TRY
914 {
915 int i;
916 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
917 const rtti_object_hierarchy *obj_bases;
918 const rtti_base_array *base_array;
919 char *base;
920
921 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
922
923 if(obj_locator->signature == 0)
924 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
925 else
926 base = (char*)obj_locator - obj_locator->object_locator;
927
928 obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy);
929 base_array = (const rtti_base_array*)(base + obj_bases->base_classes);
930
931 ret = NULL;
932 for (i = 0; i < obj_bases->array_len; i++)
933 {
934 const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]);
935 const type_info *typ = (const type_info*)(base + base_desc->type_descriptor);
936
937 if (!strcmp(typ->mangled, dst->mangled))
938 {
939 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
940 ret = get_this_pointer( &base_desc->offsets, this_ptr );
941 break;
942 }
943 }
944 if (!ret && do_throw)
945 {
946 const char *msg = "Bad dynamic_cast!";
947 bad_cast e;
948 bad_cast_ctor( &e, &msg );
949 _CxxThrowException( &e, &bad_cast_exception_type );
950 }
951 }
953 {
954 __non_rtti_object e;
955 __non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
956 _CxxThrowException( &e, &__non_rtti_object_exception_type );
957 }
959 return ret;
960}
961#endif
962
963
964/******************************************************************
965 * __RTCastToVoid (MSVCRT.@)
966 *
967 * Dynamically cast a C++ object to a void*.
968 *
969 * PARAMS
970 * cppobj [I] The C++ object to cast
971 *
972 * RETURNS
973 * Success: The base address of the object as a void*.
974 * Failure: NULL, if cppobj is NULL or has no RTTI.
975 *
976 * NOTES
977 * This function is usually called by compiler generated code as a result
978 * of using one of the C++ dynamic cast statements.
979 */
980void* CDECL __RTCastToVoid(void *cppobj)
981{
982 void *ret;
983
984 if (!cppobj) return NULL;
985
986 __TRY
987 {
988 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
989 ret = (char *)cppobj - obj_locator->base_class_offset;
990 }
992 {
993 __non_rtti_object e;
994 __non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
995 _CxxThrowException( &e, &__non_rtti_object_exception_type );
996 }
998 return ret;
999}
1000
1001
1002/*********************************************************************
1003 * _CxxThrowException (MSVCRT.@)
1004 */
1005#ifndef __x86_64__
1007{
1008 ULONG_PTR args[3];
1009
1011 args[1] = (ULONG_PTR)object;
1012 args[2] = (ULONG_PTR)type;
1014}
1015#else
1016void WINAPI _CxxThrowException( void *object, const cxx_exception_type *type )
1017{
1018 ULONG_PTR args[4];
1019
1021 args[1] = (ULONG_PTR)object;
1022 args[2] = (ULONG_PTR)type;
1023 RtlPcToFileHeader( (void*)type, (void**)&args[3]);
1025}
1026#endif
1027
1028#if _MSVCR_VER >= 80
1029
1030/*********************************************************************
1031 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
1032 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
1033 */
1034#ifndef __x86_64__
1036{
1037 int ret = -1;
1038
1039 TRACE("(%p %p)\n", ti, ep);
1040
1041 __TRY
1042 {
1044
1045 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 &&
1049 {
1050 const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table;
1051 int i;
1052
1053 for (i=0; i<tit->count; i++) {
1054 if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled))
1055 {
1056 ret = 1;
1057 break;
1058 }
1059 }
1060
1061 if (i == tit->count)
1062 ret = 0;
1063 }
1064 }
1066 __ENDTRY
1067
1068 if(ret == -1)
1069 terminate();
1070 return ret;
1071}
1072#else
1074{
1075 int ret = -1;
1076
1077 TRACE("(%p %p)\n", ti, ep);
1078
1079 __TRY
1080 {
1082
1083 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 &&
1087 {
1090 int i;
1091
1092 for (i=0; i<tit->count; i++) {
1093 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]);
1094 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info);
1095 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
1096 {
1097 ret = 1;
1098 break;
1099 }
1100 }
1101
1102 if (i == tit->count)
1103 ret = 0;
1104 }
1105 }
1107 __ENDTRY
1108
1109 if(ret == -1)
1110 terminate();
1111 return ret;
1112}
1113#endif
1114
1115/*********************************************************************
1116 * __clean_type_info_names_internal (MSVCR80.@)
1117 */
1118void CDECL __clean_type_info_names_internal(void *p)
1119{
1120 FIXME("(%p) stub\n", p);
1121}
1122
1123/*********************************************************************
1124 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
1125 */
1126DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8)
1127const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
1128{
1129 static int once;
1130 if (node && !once++) FIXME("type_info_node parameter ignored\n");
1131
1132 return type_info_name(_this);
1133}
1134
1135#endif /* _MSVCR_VER >= 80 */
1136
1137/* std::exception_ptr class helpers */
1138typedef struct
1139{
1141 int *ref; /* not binary compatible with native msvcr100 */
1143
1144#if _MSVCR_VER >= 100
1145
1146/*********************************************************************
1147 * ?__ExceptionPtrCreate@@YAXPAX@Z
1148 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1149 */
1150void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1151{
1152 TRACE("(%p)\n", ep);
1153
1154 ep->rec = NULL;
1155 ep->ref = NULL;
1156}
1157
1158#ifdef __ASM_USE_THISCALL_WRAPPER
1159extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1160
1161__ASM_GLOBAL_FUNC( call_dtor,
1162 "movl 12(%esp),%ecx\n\t"
1163 "call *8(%esp)\n\t"
1164 "ret" );
1165#elif __x86_64__
1166static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1167{
1168 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1169 void (__cdecl *func)(void*) = (void*)(base + dtor);
1170 func(object);
1171}
1172#else
1173#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1174#endif
1175
1176/*********************************************************************
1177 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1178 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1179 */
1180void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1181{
1182 TRACE("(%p)\n", ep);
1183
1184 if (!ep->rec)
1185 return;
1186
1187 if (!InterlockedDecrement(ep->ref))
1188 {
1189 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1190 {
1191 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1192 void *obj = (void*)ep->rec->ExceptionInformation[1];
1193
1194 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1196 }
1197
1198 HeapFree(GetProcessHeap(), 0, ep->rec);
1199 HeapFree(GetProcessHeap(), 0, ep->ref);
1200 }
1201}
1202
1203/*********************************************************************
1204 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1205 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1206 */
1207void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1208{
1209 TRACE("(%p %p)\n", ep, copy);
1210
1211 /* don't destroy object stored in ep */
1212 *ep = *copy;
1213 if (ep->ref)
1215}
1216
1217/*********************************************************************
1218 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1219 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1220 */
1221void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1222{
1223 TRACE("(%p %p)\n", ep, assign);
1224
1225 /* don't destroy object stored in ep */
1226 if (ep->ref)
1228
1229 *ep = *assign;
1230 if (ep->ref)
1232}
1233
1234#endif /* _MSVCR_VER >= 100 */
1235
1236/*********************************************************************
1237 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1238 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1239 */
1241{
1242 TRACE("(%p)\n", ep);
1243
1244 if (!ep->rec)
1245 {
1246 static const char *exception_msg = "bad exception";
1247 exception e;
1248
1249 exception_ctor(&e, &exception_msg);
1250 _CxxThrowException(&e, &exception_exception_type);
1251 return;
1252 }
1253
1256}
1257
1258#if _MSVCR_VER >= 100
1259
1260#ifdef __i386__
1261extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
1262#else
1263static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
1264{
1265 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
1266 if (has_vbase)
1267 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
1268 else
1269 ((void (__cdecl*)(void*, void*))func)(this, src);
1270}
1271#endif
1272
1273/*********************************************************************
1274 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1275 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1276 */
1277#ifndef __x86_64__
1278void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1279{
1280 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1281
1282 TRACE("(%p)\n", ep);
1283
1284 if (!rec)
1285 {
1286 ep->rec = NULL;
1287 ep->ref = NULL;
1288 return;
1289 }
1290
1291 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1292 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1293
1294 *ep->rec = *rec;
1295 *ep->ref = 1;
1296
1297 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1298 {
1299 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1300 const cxx_type_info *ti;
1301 void **data, *obj;
1302
1303 ti = et->type_info_table->info[0];
1304 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1305
1306 obj = (void*)ep->rec->ExceptionInformation[1];
1307 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1308 {
1309 memcpy(data, obj, ti->size);
1310 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1311 }
1312 else if (ti->copy_ctor)
1313 {
1314 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1315 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1316 }
1317 else
1318 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1320 }
1321 return;
1322}
1323#else
1324void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1325{
1326 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1327
1328 TRACE("(%p)\n", ep);
1329
1330 if (!rec)
1331 {
1332 ep->rec = NULL;
1333 ep->ref = NULL;
1334 return;
1335 }
1336
1337 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1338 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1339
1340 *ep->rec = *rec;
1341 *ep->ref = 1;
1342
1343 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1344 {
1345 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1346 const cxx_type_info *ti;
1347 void **data, *obj;
1348 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1349
1350 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1351 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1352
1353 obj = (void*)ep->rec->ExceptionInformation[1];
1354 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1355 {
1356 memcpy(data, obj, ti->size);
1357 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1358 }
1359 else if (ti->copy_ctor)
1360 {
1361 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1362 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1363 }
1364 else
1365 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1367 }
1368 return;
1369}
1370#endif
1371
1372#endif /* _MSVCR_VER >= 100 */
1373
1374#if _MSVCR_VER >= 110
1375/*********************************************************************
1376 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1377 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1378 */
1379bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1380{
1381 return !!ep->rec;
1382}
1383#endif
1384
1385#if _MSVCR_VER >= 100
1386
1387/*********************************************************************
1388 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1389 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1390 */
1391#ifndef __x86_64__
1392void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1393 exception *object, const cxx_exception_type *type)
1394{
1395 const cxx_type_info *ti;
1396 void **data;
1397
1398 __ExceptionPtrDestroy(ep);
1399
1400 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1401 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1402 *ep->ref = 1;
1403
1404 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1407 ep->rec->NumberParameters = 3;
1410
1411 ti = type->type_info_table->info[0];
1412 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1413 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1414 {
1415 memcpy(data, object, ti->size);
1416 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1417 }
1418 else if (ti->copy_ctor)
1419 {
1420 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1422 }
1423 else
1424 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1426}
1427#else
1428void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1429 exception *object, const cxx_exception_type *type)
1430{
1431 const cxx_type_info *ti;
1432 void **data;
1433 char *base;
1434
1435 RtlPcToFileHeader((void*)type, (void**)&base);
1436 __ExceptionPtrDestroy(ep);
1437
1438 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1439 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1440 *ep->ref = 1;
1441
1442 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1445 ep->rec->NumberParameters = 4;
1449
1450 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
1451 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1452 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1453 {
1454 memcpy(data, object, ti->size);
1455 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1456 }
1457 else if (ti->copy_ctor)
1458 {
1459 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1461 }
1462 else
1463 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1465}
1466#endif
1467
1468bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
1469{
1470 return ep1->rec == ep2->rec;
1471}
1472
1473#endif /* _MSVCR_VER >= 100 */
1474
1475#if _MSVCR_VER >= 80
1476void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
1477{
1478 return get_this_pointer(off, obj);
1479}
1480#endif
1481
1482#if _MSVCR_VER >= 140
1483
1484typedef struct
1485{
1486 char *name;
1487 char mangled[1];
1488} type_info140;
1489
1490typedef struct
1491{
1493 char name[1];
1494} type_info_entry;
1495
1496static void* CDECL type_info_entry_malloc(size_t size)
1497{
1498 type_info_entry *ret = malloc(FIELD_OFFSET(type_info_entry, name) + size);
1499 return ret->name;
1500}
1501
1502static void CDECL type_info_entry_free(void *ptr)
1503{
1504 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
1505 free(ptr);
1506}
1507
1508/******************************************************************
1509 * __std_type_info_compare (UCRTBASE.@)
1510 */
1511int CDECL __std_type_info_compare(const type_info140 *l, const type_info140 *r)
1512{
1513 int ret;
1514
1515 if (l == r) ret = 0;
1516 else ret = strcmp(l->mangled + 1, r->mangled + 1);
1517 TRACE("(%p %p) returning %d\n", l, r, ret);
1518 return ret;
1519}
1520
1521/******************************************************************
1522 * __std_type_info_name (UCRTBASE.@)
1523 */
1524const char* CDECL __std_type_info_name(type_info140 *ti, SLIST_HEADER *header)
1525{
1526 if (!ti->name)
1527 {
1528 char* name = __unDName(0, ti->mangled + 1, 0,
1529 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
1530 if (name)
1531 {
1532 unsigned int len = strlen(name);
1533
1534 while (len && name[--len] == ' ')
1535 name[len] = '\0';
1536
1537 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
1538 {
1539 type_info_entry_free(name);
1540 }
1541 else
1542 {
1543 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
1545 }
1546 }
1547 }
1548 TRACE("(%p) returning %s\n", ti, ti->name);
1549 return ti->name;
1550}
1551
1552/******************************************************************
1553 * __std_type_info_destroy_list (UCRTBASE.@)
1554 */
1555void CDECL __std_type_info_destroy_list(SLIST_HEADER *header)
1556{
1557 SLIST_ENTRY *cur, *next;
1558
1559 TRACE("(%p)\n", header);
1560
1562 {
1563 next = cur->Next;
1564 free(cur);
1565 }
1566}
1567
1568/******************************************************************
1569 * __std_type_info_hash (UCRTBASE.@)
1570 */
1571size_t CDECL __std_type_info_hash(const type_info140 *ti)
1572{
1573 size_t hash, fnv_prime;
1574 const char *p;
1575
1576#ifdef _WIN64
1577 hash = 0xcbf29ce484222325;
1578 fnv_prime = 0x100000001b3;
1579#else
1580 hash = 0x811c9dc5;
1581 fnv_prime = 0x1000193;
1582#endif
1583
1584 TRACE("(%p)->%s\n", ti, ti->mangled);
1585
1586 for(p = ti->mangled+1; *p; p++) {
1587 hash ^= *p;
1588 hash *= fnv_prime;
1589 }
1590
1591#ifdef _WIN64
1592 hash ^= hash >> 32;
1593#endif
1594
1595 return hash;
1596}
1597
1598#endif /* _MSVCR_VER >= 140 */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define __cdecl
Definition: accygwin.h:79
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
r l[0]
Definition: byte_order.h:168
FxCollectionEntry * Next(VOID)
#define CREATE_TYPE_INFO_VTABLE
Definition: cxx.h:293
#define __ASM_VTABLE(name, funcs)
Definition: cxx.h:40
#define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name)
Definition: cxx.h:181
#define VTABLE_ADD_FUNC(name)
Definition: cxx.h:38
#define DEFINE_RTTI_DATA0(name, off, mangled_name)
Definition: cxx.h:179
#define UNDNAME_32_BIT_DECODE
Definition: dbghelp.h:1264
#define UNDNAME_NO_ARGUMENTS
Definition: dbghelp.h:1266
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:658
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define CDECL
Definition: compat.h:29
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#define HeapFree(x, y, z)
Definition: compat.h:735
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
unsigned char
Definition: typeof.h:29
#define ULONG_PTR
Definition: config.h:101
static const FxOffsetAndName offsets[]
FxCollectionEntry * cur
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define abort()
Definition: i386-dis.c:34
#define CXX_EXCEPTION
Definition: cppexcept.h:27
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:155
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:127
#define CXX_FRAME_MAGIC_VC7
Definition: cppexcept.h:25
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:24
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:128
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:26
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:163
void(__cdecl * _se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS *)
Definition: eh.h:29
void(__cdecl * unexpected_function)(void)
Definition: eh.h:25
_CRTIMP int __cdecl _is_exception_typeof(const type_info &_Type, struct _EXCEPTION_POINTERS *_ExceptionPtr)
void(__cdecl * terminate_function)(void)
Definition: eh.h:23
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static void * get_obj_locator(void *cppobj)
Definition: cpp.c:885
#define __thiscall
Definition: cpp.c:43
void(* vtable_ptr)(void)
Definition: cpp.c:23
static unsigned int
Definition: cpp.c:62
static vtable_ptr * get_vtable(void *obj)
Definition: cpp.c:880
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
char *__cdecl __unDName(char *, const char *, int, malloc_func_t, free_func_t, unsigned short int)
Definition: undname.c:1650
static void * vtable[]
Definition: typelib.c:1231
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
Definition: features.h:417
#define BOOL
Definition: nt_native.h:43
#define DEFINE_THISCALL_WRAPPER(func, args)
Definition: msvc-thiscall.c:2
static unsigned __int64 next
Definition: rand_nt.c:6
#define __ASM_BLOCK_END
Definition: asm.h:60
#define __ASM_BLOCK_BEGIN(name)
Definition: asm.h:59
#define EH_UNWINDING
Definition: exception.h:17
unexpected_function CDECL set_unexpected(unexpected_function func)
Definition: cpp.c:672
void __thiscall bad_typeid_dtor(bad_typeid *_this)
Definition: cpp.c:220
void WINAPI _CxxThrowException(void *object, const cxx_exception_type *type)
Definition: cpp.c:1006
void *__thiscall bad_cast_scalar_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:439
void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
Definition: cpp.c:1240
void __thiscall type_info_dtor(type_info *_this)
Definition: cpp.c:484
const vtable_ptr bad_typeid_vtable
bad_cast *__thiscall bad_cast_copy_ctor(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:366
void CDECL unexpected(void)
Definition: cpp.c:726
void __thiscall bad_cast_dtor(bad_cast *_this)
Definition: cpp.c:395
int __thiscall type_info_before(type_info *_this, const type_info *rhs)
Definition: cpp.c:473
void *__thiscall bad_typeid_scalar_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:264
void *CDECL __RTCastToVoid(void *cppobj)
Definition: cpp.c:980
bad_cast *__thiscall bad_cast_ctor(bad_cast *_this, const char **name)
Definition: cpp.c:356
_se_translator_function CDECL _set_se_translator(_se_translator_function func)
Definition: cpp.c:694
exception __thiscall exception_default_ctor(exception *_this)
Definition: cpp.c:153
void *__thiscall bad_cast_vector_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:416
void CDECL terminate(void)
Definition: cpp.c:716
void *__thiscall __non_rtti_object_scalar_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:343
static void dump_obj_locator(const rtti_object_locator *ptr)
Definition: cpp.c:66
const char *__thiscall type_info_name(type_info *_this)
Definition: cpp.c:494
const type_info *CDECL __RTtypeid(void *cppobj)
Definition: cpp.c:753
__non_rtti_object *__thiscall __non_rtti_object_copy_ctor(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:276
int __thiscall type_info_opequals_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:451
void *__thiscall exception_scalar_dtor(exception *_this, unsigned int flags)
Definition: cpp.c:179
bad_typeid *__thiscall bad_typeid_copy_ctor(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:191
const vtable_ptr type_info_vtable
const vtable_ptr bad_cast_vtable
void *CDECL __RTDynamicCast(void *cppobj, int unknown, type_info *src, type_info *dst, int do_throw)
Definition: cpp.c:838
void *__thiscall bad_typeid_vector_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:241
const char *__thiscall type_info_raw_name(type_info *_this)
Definition: cpp.c:528
void __thiscall __non_rtti_object_dtor(__non_rtti_object *_this)
Definition: cpp.c:298
void *__thiscall __non_rtti_object_vector_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:320
int __thiscall type_info_opnot_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:462
bad_typeid *__thiscall bad_typeid_opequals(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:230
bad_cast *__thiscall bad_cast_ctor_charptr(bad_cast *_this, const char *name)
Definition: cpp.c:376
__non_rtti_object *__thiscall __non_rtti_object_opequals(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:308
unexpected_function CDECL _get_unexpected(void)
Definition: cpp.c:684
bad_cast *__thiscall bad_cast_opequals(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:405
bad_typeid *__thiscall bad_typeid_default_ctor(bad_typeid *_this)
Definition: cpp.c:211
exception __thiscall exception_ctor(exception *_this, const char **name)
Definition: cpp.c:130
exception __thiscall exception_opequals(exception *_this, const exception *rhs)
Definition: cpp.c:163
terminate_function CDECL _get_terminate(void)
Definition: cpp.c:654
bad_typeid *__thiscall bad_typeid_ctor(bad_typeid *_this, const char *name)
Definition: cpp.c:201
terminate_function CDECL set_terminate(terminate_function func)
Definition: cpp.c:642
__non_rtti_object *__thiscall __non_rtti_object_ctor(__non_rtti_object *_this, const char *name)
Definition: cpp.c:287
bad_cast *__thiscall bad_cast_default_ctor(bad_cast *_this)
Definition: cpp.c:386
exception __thiscall exception_ctor_noalloc(exception *_this, char **name, int noalloc)
Definition: cpp.c:140
const vtable_ptr __non_rtti_object_vtable
void CDECL DECLSPEC_HOTPATCH operator_delete(void *mem)
Definition: heap.c:198
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
const cxx_type_info_table * type_info_table
Definition: cppexcept.h:148
const cxx_type_info * info[3]
Definition: cppexcept.h:134
cxx_copy_ctor copy_ctor
Definition: cppexcept.h:125
const type_info * type_info
Definition: cppexcept.h:122
this_ptr_offsets offsets
Definition: cppexcept.h:123
unsigned int size
Definition: cppexcept.h:124
struct __type_info_node * next
Definition: cpp.c:41
void * memPtr
Definition: cpp.c:40
char mangled[16]
Definition: cpp.c:36
const rtti_base_descriptor * bases[10]
Definition: cxx.h:206
this_ptr_offsets offsets
Definition: cxx.h:200
int num_base_classes
Definition: cxx.h:199
const type_info * type_descriptor
Definition: cxx.h:198
unsigned int attributes
Definition: cxx.h:201
const rtti_base_array * base_classes
Definition: cxx.h:214
const type_info * type_descriptor
Definition: cxx.h:222
unsigned int signature
Definition: cxx.h:219
int base_class_offset
Definition: cxx.h:220
const rtti_object_hierarchy * type_hierarchy
Definition: cxx.h:223
Definition: match.c:390
EXCEPTION_RECORD * rec
Definition: cpp.c:1140
int * ref
Definition: cpp.c:1141
Definition: _hash_fun.h:40
Definition: name.c:39
#define EH_NONCONTINUABLE
Definition: stubs.h:32
#define SLIST_ENTRY(type)
Definition: queue.h:102
int32_t INT_PTR
Definition: typedefs.h:64
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65
Definition: dlist.c:348
int ret
#define WINAPI
Definition: msvc.h:6
#define CREATE_EXCEPTION_OBJECT(exception_name)
Definition: cppexcept.h:251
exception __thiscall exception_copy_ctor(exception *_this, const exception *rhs)
void __thiscall exception_dtor(exception *_this)
void *__thiscall exception_vector_dtor(exception *_this, unsigned int flags)
const char *__thiscall exception_what(exception *_this)
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406
#define InterlockedFlushSList(SListHead)
Definition: rtlfuncs.h:3412
#define const
Definition: zconf.h:233