ReactOS 0.4.16-dev-2284-g3529151
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 "winbase.h"
28#include "winver.h"
29#include "imagehlp.h"
30#include "wine/exception.h"
31#include "wine/debug.h"
32#include "msvcrt.h"
33#include "mtdll.h"
34#include "cppexcept.h"
35
37
40
42{
43 void *memPtr;
45};
46
47typedef exception bad_cast;
48typedef exception bad_typeid;
50
51extern const vtable_ptr bad_typeid_vtable;
52extern const vtable_ptr bad_cast_vtable;
54extern const vtable_ptr type_info_vtable;
55
56/* get the vtable pointer for a C++ object */
57static inline const vtable_ptr *get_vtable( void *obj )
58{
59 return *(const vtable_ptr **)obj;
60}
61
62static inline const rtti_object_locator *get_obj_locator( void *cppobj )
63{
64 const vtable_ptr *vtable = get_vtable( cppobj );
65 return (const rtti_object_locator *)vtable[-1];
66}
67
69{
70#ifdef RTTI_USE_RVA
71 if (ptr->signature) return (uintptr_t)ptr - ptr->object_locator;
72#endif
73 return rtti_rva_base( ptr );
74}
75
77{
78 int i;
80 const rtti_object_hierarchy *h = rtti_rva( ptr->type_hierarchy, base );
81 const type_info *type_descriptor = rtti_rva( ptr->type_descriptor, base );
82
83 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
84 ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
85 type_descriptor, dbgstr_type_info(type_descriptor), h );
86 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
87 h->signature, h->attributes, h->array_len, rtti_rva(h->base_classes, base) );
88 for (i = 0; i < h->array_len; i++)
89 {
90 const rtti_base_array *base_array = rtti_rva( h->base_classes, base );
91 const rtti_base_descriptor *bases = rtti_rva( base_array->bases[i], base );
92
93 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
94 bases, bases->num_base_classes, bases->offsets.this_offset,
95 bases->offsets.vbase_descr, bases->offsets.vbase_offset, bases->attributes,
96 rtti_rva( bases->type_descriptor, base ),
97 dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) );
98 }
99}
100
101/******************************************************************
102 * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
103 */
106{
107 TRACE("(%p,%s)\n", _this, *name);
108 return __exception_ctor(_this, *name, &exception_vtable);
109}
110
111/******************************************************************
112 * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
113 */
116{
117 TRACE("(%p,%s)\n", _this, *name);
118 _this->vtable = &exception_vtable;
119 _this->name = *name;
120 _this->do_free = FALSE;
121 return _this;
122}
123
124/******************************************************************
125 * ??0exception@@QAE@XZ (MSVCRT.@)
126 */
129{
130 TRACE("(%p)\n", _this);
131 return __exception_ctor(_this, NULL, &exception_vtable);
132}
133
134/******************************************************************
135 * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
136 */
139{
140 TRACE("(%p %p)\n", _this, rhs);
141 if (_this != rhs)
142 {
143 exception_dtor(_this);
144 exception_copy_ctor(_this, rhs);
145 }
146 TRACE("name = %s\n", _this->name);
147 return _this;
148}
149
150/******************************************************************
151 * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
152 */
155{
156 TRACE("(%p %x)\n", _this, flags);
157 exception_dtor(_this);
158 if (flags & 1) operator_delete(_this);
159 return _this;
160}
161
162/******************************************************************
163 * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
164 */
167{
168 TRACE("(%p %p)\n", _this, rhs);
169 return __exception_copy_ctor(_this, rhs, &bad_typeid_vtable);
170}
171
172/******************************************************************
173 * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
174 */
177{
178 TRACE("(%p %s)\n", _this, name);
179 return __exception_ctor(_this, name, &bad_typeid_vtable);
180}
181
182/******************************************************************
183 * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
184 */
187{
188 return bad_typeid_ctor( _this, "bad typeid" );
189}
190
191/******************************************************************
192 * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
193 */
196{
197 TRACE("(%p)\n", _this);
198 exception_dtor(_this);
199}
200
201/******************************************************************
202 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
203 */
206{
207 TRACE("(%p %p)\n", _this, rhs);
208 exception_opequals(_this, rhs);
209 return _this;
210}
211
212/******************************************************************
213 * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
214 */
217{
218 TRACE("(%p %x)\n", _this, flags);
219 if (flags & 2)
220 {
221 /* we have an array, with the number of elements stored before the first object */
222 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
223
224 for (i = *ptr - 1; i >= 0; i--) bad_typeid_dtor(_this + i);
226 }
227 else
228 {
229 bad_typeid_dtor(_this);
230 if (flags & 1) operator_delete(_this);
231 }
232 return _this;
233}
234
235/******************************************************************
236 * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
237 */
240{
241 TRACE("(%p %x)\n", _this, flags);
242 bad_typeid_dtor(_this);
243 if (flags & 1) operator_delete(_this);
244 return _this;
245}
246
247/******************************************************************
248 * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
249 */
253{
254 TRACE("(%p %p)\n", _this, rhs);
255 return __exception_copy_ctor(_this, rhs, &__non_rtti_object_vtable);
256}
257
258/******************************************************************
259 * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
260 */
263 const char * name)
264{
265 TRACE("(%p %s)\n", _this, name);
266 return __exception_ctor(_this, name, &__non_rtti_object_vtable);
267}
268
269/******************************************************************
270 * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
271 */
274{
275 TRACE("(%p)\n", _this);
276 bad_typeid_dtor(_this);
277}
278
279/******************************************************************
280 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
281 */
285{
286 TRACE("(%p %p)\n", _this, rhs);
287 bad_typeid_opequals(_this, rhs);
288 return _this;
289}
290
291/******************************************************************
292 * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
293 */
296{
297 TRACE("(%p %x)\n", _this, flags);
298 if (flags & 2)
299 {
300 /* we have an array, with the number of elements stored before the first object */
301 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
302
303 for (i = *ptr - 1; i >= 0; i--) __non_rtti_object_dtor(_this + i);
305 }
306 else
307 {
309 if (flags & 1) operator_delete(_this);
310 }
311 return _this;
312}
313
314/******************************************************************
315 * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
316 */
319{
320 TRACE("(%p %x)\n", _this, flags);
322 if (flags & 1) operator_delete(_this);
323 return _this;
324}
325
326/******************************************************************
327 * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
328 * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
329 */
332{
333 TRACE("(%p %s)\n", _this, *name);
334 return __exception_ctor(_this, *name, &bad_cast_vtable);
335}
336
337/******************************************************************
338 * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
339 */
342{
343 TRACE("(%p %p)\n", _this, rhs);
344 return __exception_copy_ctor(_this, rhs, &bad_cast_vtable);
345}
346
347/******************************************************************
348 * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
349 */
352{
353 TRACE("(%p %s)\n", _this, name);
354 return __exception_ctor(_this, name, &bad_cast_vtable);
355}
356
357/******************************************************************
358 * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
359 */
362{
363 return bad_cast_ctor_charptr( _this, "bad cast" );
364}
365
366/******************************************************************
367 * ??1bad_cast@@UAE@XZ (MSVCRT.@)
368 */
371{
372 TRACE("(%p)\n", _this);
373 exception_dtor(_this);
374}
375
376/******************************************************************
377 * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
378 */
381{
382 TRACE("(%p %p)\n", _this, rhs);
383 exception_opequals(_this, rhs);
384 return _this;
385}
386
387/******************************************************************
388 * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
389 */
392{
393 TRACE("(%p %x)\n", _this, flags);
394 if (flags & 2)
395 {
396 /* we have an array, with the number of elements stored before the first object */
397 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
398
399 for (i = *ptr - 1; i >= 0; i--) bad_cast_dtor(_this + i);
401 }
402 else
403 {
404 bad_cast_dtor(_this);
405 if (flags & 1) operator_delete(_this);
406 }
407 return _this;
408}
409
410/******************************************************************
411 * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
412 */
415{
416 TRACE("(%p %x)\n", _this, flags);
417 bad_cast_dtor(_this);
418 if (flags & 1) operator_delete(_this);
419 return _this;
420}
421
422/******************************************************************
423 * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
424 */
427{
428 int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1);
429 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
430 return ret;
431}
432
433/******************************************************************
434 * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
435 */
438{
439 int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1);
440 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
441 return ret;
442}
443
444/******************************************************************
445 * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
446 */
449{
450 int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0;
451 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
452 return ret;
453}
454
455/******************************************************************
456 * ??1type_info@@UAE@XZ (MSVCRT.@)
457 */
460{
461 TRACE("(%p)\n", _this);
462 free(_this->name);
463}
464
465/******************************************************************
466 * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
467 */
470{
471 if (!_this->name)
472 {
473 /* Create and set the demangled name */
474 /* Note: mangled name in type_info struct always starts with a '.', while
475 * it isn't valid for mangled name.
476 * Is this '.' really part of the mangled name, or has it some other meaning ?
477 */
478 char* name = __unDName(0, _this->mangled + 1, 0,
480 if (name)
481 {
482 unsigned int len = strlen(name);
483
484 /* It seems _unDName may leave blanks at the end of the demangled name */
485 while (len && name[--len] == ' ')
486 name[len] = '\0';
487
488 if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
489 {
490 /* Another thread set this member since we checked above - use it */
491 free(name);
492 }
493 }
494 }
495 TRACE("(%p) returning %s\n", _this, _this->name);
496 return _this->name;
497}
498
499/******************************************************************
500 * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
501 */
504{
505 TRACE("(%p) returning %s\n", _this, _this->mangled);
506 return _this->mangled;
507}
508
509#if _MSVCR_VER >= 80
510
511typedef exception bad_alloc;
512extern const vtable_ptr bad_alloc_vtable;
513
514/* bad_alloc class implementation */
515DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor,8)
516bad_alloc * __thiscall bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs)
517{
518 TRACE("(%p %p)\n", _this, rhs);
519 return __exception_copy_ctor(_this, rhs, &bad_alloc_vtable);
520}
521
522DEFINE_THISCALL_WRAPPER(bad_alloc_dtor,4)
523void __thiscall bad_alloc_dtor(bad_alloc * _this)
524{
525 TRACE("(%p)\n", _this);
526 exception_dtor(_this);
527}
528
529#endif /* _MSVCR_VER >= 80 */
530
531__ASM_BLOCK_BEGIN(vtables)
532
533#if _MSVCR_VER >= 80
534__ASM_VTABLE(exception_old,
537__ASM_VTABLE(bad_alloc,
540#endif
550
552
553#if _MSVCR_VER >= 80
554DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" )
555DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" )
556DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" )
557DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" )
558DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" )
559#else
560DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" )
561DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" )
562DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" )
563#endif
564
565DEFINE_CXX_DATA0( exception, exception_dtor )
566DEFINE_CXX_DATA1( bad_typeid, &exception_cxx_type_info, bad_typeid_dtor )
567DEFINE_CXX_DATA1( bad_cast, &exception_cxx_type_info, bad_cast_dtor )
568DEFINE_CXX_DATA2( __non_rtti_object, &bad_typeid_cxx_type_info,
569 &exception_cxx_type_info, __non_rtti_object_dtor )
570#if _MSVCR_VER >= 80
571DEFINE_CXX_DATA1( bad_alloc, &exception_cxx_type_info, bad_alloc_dtor )
572#endif
573
574void msvcrt_init_exception(void *base)
575{
576#ifdef RTTI_USE_RVA
577 init_type_info_rtti(base);
578 init_exception_rtti(base);
579#if _MSVCR_VER >= 80
580 init_exception_old_rtti(base);
581 init_bad_alloc_rtti(base);
582#endif
583 init_bad_typeid_rtti(base);
584 init_bad_cast_rtti(base);
585 init___non_rtti_object_rtti(base);
586
587 init_exception_cxx(base);
588 init_bad_typeid_cxx(base);
589 init_bad_cast_cxx(base);
590 init___non_rtti_object_cxx(base);
591#if _MSVCR_VER >= 80
592 init_bad_alloc_cxx(base);
593#endif
594#endif
595}
596
597#if _MSVCR_VER >= 80
598void throw_bad_alloc(void)
599{
600 bad_alloc e;
601 __exception_ctor(&e, "bad allocation", &bad_alloc_vtable);
602 _CxxThrowException(&e, &bad_alloc_exception_type);
603}
604#endif
605
606void throw_exception(const char* msg)
607{
608 exception e;
609 __exception_ctor(&e, msg, &exception_vtable);
610 _CxxThrowException(&e, &exception_exception_type);
611}
612
613#ifndef __UCRTSUPPORT__
614/******************************************************************
615 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
616 *
617 * Install a handler to be called when terminate() is called.
618 *
619 * PARAMS
620 * func [I] Handler function to install
621 *
622 * RETURNS
623 * The previously installed handler function, if any.
624 */
626{
628 terminate_function previous = data->terminate_handler;
629 TRACE("(%p) returning %p\n",func,previous);
630 data->terminate_handler = func;
631 return previous;
632}
633
634/******************************************************************
635 * _get_terminate (MSVCRT.@)
636 */
638{
640 TRACE("returning %p\n", data->terminate_handler);
641 return data->terminate_handler;
642}
643#endif /* !__UCRTSUPPORT__ */
644
645/******************************************************************
646 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
647 *
648 * Install a handler to be called when unexpected() is called.
649 *
650 * PARAMS
651 * func [I] Handler function to install
652 *
653 * RETURNS
654 * The previously installed handler function, if any.
655 */
657{
659 unexpected_function previous = data->unexpected_handler;
660 TRACE("(%p) returning %p\n",func,previous);
661 data->unexpected_handler = func;
662 return previous;
663}
664
665/******************************************************************
666 * _get_unexpected (MSVCRT.@)
667 */
669{
671 TRACE("returning %p\n", data->unexpected_handler);
672 return data->unexpected_handler;
673}
674
675/******************************************************************
676 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
677 */
679{
681 _se_translator_function previous = data->se_translator;
682 TRACE("(%p) returning %p\n",func,previous);
683 data->se_translator = func;
684 return previous;
685}
686
687#ifndef __UCRTSUPPORT__
688/******************************************************************
689 * ?terminate@@YAXXZ (MSVCRT.@)
690 *
691 * Default handler for an unhandled exception.
692 *
693 * PARAMS
694 * None.
695 *
696 * RETURNS
697 * This function does not return. Either control resumes from any
698 * handler installed by calling set_terminate(), or (by default) abort()
699 * is called.
700 */
701void CDECL terminate(void)
702{
704 if (data->terminate_handler) data->terminate_handler();
705 abort();
706}
707
708/******************************************************************
709 * ?unexpected@@YAXXZ (MSVCRT.@)
710 */
712{
714 if (data->unexpected_handler) data->unexpected_handler();
715 terminate();
716}
717#endif /* !__UCRTSUPPORT__ */
718
719
720/******************************************************************
721 * __RTtypeid (MSVCRT.@)
722 *
723 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
724 *
725 * PARAMS
726 * cppobj [I] C++ object to get type information for.
727 *
728 * RETURNS
729 * Success: A type_info object describing cppobj.
730 * Failure: If the object to be cast has no RTTI, a __non_rtti_object
731 * exception is thrown. If cppobj is NULL, a bad_typeid exception
732 * is thrown. In either case, this function does not return.
733 *
734 * NOTES
735 * This function is usually called by compiler generated code as a result
736 * of using one of the C++ dynamic cast statements.
737 */
738const type_info* CDECL __RTtypeid(void *cppobj)
739{
740 const type_info *ret;
741
742 if (!cppobj)
743 {
745 bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
746 _CxxThrowException( &e, &bad_typeid_exception_type );
747 }
748
749 __TRY
750 {
751 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
752 uintptr_t base = get_obj_locator_base( obj_locator );
753
754 ret = rtti_rva( obj_locator->type_descriptor, base );
755 }
757 {
759 __non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
760 _CxxThrowException( &e, &__non_rtti_object_exception_type );
761 }
763 return ret;
764}
765
766/******************************************************************
767 * __RTDynamicCast (MSVCRT.@)
768 *
769 * Dynamically cast a C++ object to one of its base classes.
770 *
771 * PARAMS
772 * cppobj [I] Any C++ object to cast
773 * unknown [I] Reserved, set to 0
774 * src [I] type_info object describing cppobj
775 * dst [I] type_info object describing the base class to cast to
776 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
777 *
778 * RETURNS
779 * Success: The address of cppobj, cast to the object described by dst.
780 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
781 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
782 * is thrown and this function does not return.
783 *
784 * NOTES
785 * This function is usually called by compiler generated code as a result
786 * of using one of the C++ dynamic cast statements.
787 */
788void* CDECL __RTDynamicCast(void *cppobj, int unknown,
790 int do_throw)
791{
792 void *ret;
793
794 if (!cppobj) return NULL;
795
796 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
797 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
798
799 /* To cast an object at runtime:
800 * 1.Find out the true type of the object from the typeinfo at vtable[-1]
801 * 2.Search for the destination type in the class hierarchy
802 * 3.If destination type is found, return base object address + dest offset
803 * Otherwise, fail the cast
804 *
805 * FIXME: the unknown parameter doesn't seem to be used for anything
806 */
807 __TRY
808 {
809 int i;
810 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
811 uintptr_t base = get_obj_locator_base( obj_locator );
812 const rtti_object_hierarchy *obj_bases = rtti_rva( obj_locator->type_hierarchy, base );
813 const rtti_base_array *base_array = rtti_rva( obj_bases->base_classes, base );
814
815 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
816
817 ret = NULL;
818 for (i = 0; i < obj_bases->array_len; i++)
819 {
820 const rtti_base_descriptor *base_desc = rtti_rva( base_array->bases[i], base );
821 const type_info *typ = rtti_rva( base_desc->type_descriptor, base );
822
823 if (!strcmp(typ->mangled, dst->mangled))
824 {
825 /* compute the correct this pointer for that base class */
826 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
827 ret = get_this_pointer( &base_desc->offsets, this_ptr );
828 break;
829 }
830 }
831 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
832 * to a reference, since references cannot be NULL.
833 */
834 if (!ret && do_throw)
835 {
836 const char *msg = "Bad dynamic_cast!";
837 bad_cast e;
838 bad_cast_ctor( &e, &msg );
839 _CxxThrowException( &e, &bad_cast_exception_type );
840 }
841 }
843 {
845 __non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
846 _CxxThrowException( &e, &__non_rtti_object_exception_type );
847 }
849 return ret;
850}
851
852
853/******************************************************************
854 * __RTCastToVoid (MSVCRT.@)
855 *
856 * Dynamically cast a C++ object to a void*.
857 *
858 * PARAMS
859 * cppobj [I] The C++ object to cast
860 *
861 * RETURNS
862 * Success: The base address of the object as a void*.
863 * Failure: NULL, if cppobj is NULL or has no RTTI.
864 *
865 * NOTES
866 * This function is usually called by compiler generated code as a result
867 * of using one of the C++ dynamic cast statements.
868 */
869void* CDECL __RTCastToVoid(void *cppobj)
870{
871 void *ret;
872
873 if (!cppobj) return NULL;
874
875 __TRY
876 {
877 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
878 ret = (char *)cppobj - obj_locator->base_class_offset;
879 }
881 {
883 __non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
884 _CxxThrowException( &e, &__non_rtti_object_exception_type );
885 }
887 return ret;
888}
889
890
891/*********************************************************************
892 * _CxxThrowException (MSVCRT.@)
893 */
895{
897
899 args[1] = (ULONG_PTR)object;
900 args[2] = (ULONG_PTR)type;
903}
904
905#if _MSVCR_VER >= 80 || defined(__UCRTSUPPORT__)
906
907/*********************************************************************
908 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
909 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
910 */
912{
913 int ret = -1;
914
915 TRACE("(%p %p)\n", ti, ep);
916
917 __TRY
918 {
920
921 if (is_cxx_exception( rec ))
922 {
926 int i;
927
928 for (i=0; i<tit->count; i++)
929 {
930 const cxx_type_info *cti = rtti_rva( tit->info[i], base );
931 const type_info *except_ti = rtti_rva( cti->type_info, base );
932 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
933 {
934 ret = 1;
935 break;
936 }
937 }
938
939 if (i == tit->count)
940 ret = 0;
941 }
942 }
945
946 if(ret == -1)
947 terminate();
948 return ret;
949}
950
951/*********************************************************************
952 * __clean_type_info_names_internal (MSVCR80.@)
953 */
954void CDECL __clean_type_info_names_internal(void *p)
955{
956 FIXME("(%p) stub\n", p);
957}
958
959/*********************************************************************
960 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
961 */
964{
965 static int once;
966 if (node && !once++) FIXME("type_info_node parameter ignored\n");
967
968 return type_info_name(_this);
969}
970
971void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
972{
973 return get_this_pointer(off, obj);
974}
975
976#endif
977
978#if _MSVCR_VER >= 140 || defined(__UCRTSUPPORT__)
979
980typedef struct
981{
982 char *name;
983 char mangled[1];
985
986typedef struct
987{
989 char name[1];
990} type_info_entry;
991
992static void* CDECL type_info_entry_malloc(size_t size)
993{
994 type_info_entry *ret = malloc(FIELD_OFFSET(type_info_entry, name) + size);
995 return ret->name;
996}
997
998static void CDECL type_info_entry_free(void *ptr)
999{
1000 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
1001 free(ptr);
1002}
1003
1004/******************************************************************
1005 * __std_type_info_compare (UCRTBASE.@)
1006 */
1007int CDECL __std_type_info_compare(const type_info140 *l, const type_info140 *r)
1008{
1009 int ret;
1010
1011 if (l == r) ret = 0;
1012 else ret = strcmp(l->mangled + 1, r->mangled + 1);
1013 TRACE("(%p %p) returning %d\n", l, r, ret);
1014 return ret;
1015}
1016
1017/******************************************************************
1018 * __std_type_info_name (UCRTBASE.@)
1019 */
1020const char* CDECL __std_type_info_name(type_info140 *ti, SLIST_HEADER *header)
1021{
1022 if (!ti->name)
1023 {
1024 char* name = __unDName(0, ti->mangled + 1, 0,
1025 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
1026 if (name)
1027 {
1028 unsigned int len = strlen(name);
1029
1030 while (len && name[--len] == ' ')
1031 name[len] = '\0';
1032
1033 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
1034 {
1035 type_info_entry_free(name);
1036 }
1037 else
1038 {
1039 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
1041 }
1042 }
1043 }
1044 TRACE("(%p) returning %s\n", ti, ti->name);
1045 return ti->name;
1046}
1047
1048/******************************************************************
1049 * __std_type_info_destroy_list (UCRTBASE.@)
1050 */
1051void CDECL __std_type_info_destroy_list(SLIST_HEADER *header)
1052{
1053 SLIST_ENTRY *cur, *next;
1054
1055 TRACE("(%p)\n", header);
1056
1058 {
1059 next = cur->Next;
1060 free(cur);
1061 }
1062}
1063
1064/******************************************************************
1065 * __std_type_info_hash (UCRTBASE.@)
1066 */
1067size_t CDECL __std_type_info_hash(const type_info140 *ti)
1068{
1069 size_t hash, fnv_prime;
1070 const char *p;
1071
1072#ifdef _WIN64
1073 hash = 0xcbf29ce484222325;
1074 fnv_prime = 0x100000001b3;
1075#else
1076 hash = 0x811c9dc5;
1077 fnv_prime = 0x1000193;
1078#endif
1079
1080 TRACE("(%p)->%s\n", ti, ti->mangled);
1081
1082 for(p = ti->mangled+1; *p; p++) {
1083 hash ^= *p;
1084 hash *= fnv_prime;
1085 }
1086
1087#ifdef _WIN64
1088 hash ^= hash >> 32;
1089#endif
1090
1091 return hash;
1092}
1093
1094#endif /* _MSVCR_VER >= 140 */
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
r l[0]
Definition: byte_order.h:168
FxCollectionEntry * Next(VOID)
#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
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define CDECL
Definition: compat.h:29
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#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
unexpected_function CDECL set_unexpected(unexpected_function func)
Definition: cpp.c:656
void __thiscall bad_typeid_dtor(bad_typeid *_this)
Definition: cpp.c:195
void WINAPI _CxxThrowException(void *object, const cxx_exception_type *type)
Definition: cpp.c:894
void throw_exception(const char *msg)
Definition: cpp.c:606
void *__thiscall bad_cast_scalar_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:414
void __thiscall type_info_dtor(type_info *_this)
Definition: cpp.c:459
const vtable_ptr bad_typeid_vtable
bad_cast *__thiscall bad_cast_copy_ctor(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:341
void CDECL unexpected(void)
Definition: cpp.c:711
void __thiscall bad_cast_dtor(bad_cast *_this)
Definition: cpp.c:370
int __thiscall type_info_before(type_info *_this, const type_info *rhs)
Definition: cpp.c:448
void *__thiscall bad_typeid_scalar_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:239
void *CDECL __RTCastToVoid(void *cppobj)
Definition: cpp.c:869
bad_cast *__thiscall bad_cast_ctor(bad_cast *_this, const char **name)
Definition: cpp.c:331
_se_translator_function CDECL _set_se_translator(_se_translator_function func)
Definition: cpp.c:678
exception __thiscall exception_default_ctor(exception *_this)
Definition: cpp.c:128
static const vtable_ptr * get_vtable(void *obj)
Definition: cpp.c:57
void *__thiscall bad_cast_vector_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:391
void CDECL terminate(void)
Definition: cpp.c:701
void *__thiscall __non_rtti_object_scalar_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:318
static void dump_obj_locator(const rtti_object_locator *ptr)
Definition: cpp.c:76
const char *__thiscall type_info_name(type_info *_this)
Definition: cpp.c:469
const type_info *CDECL __RTtypeid(void *cppobj)
Definition: cpp.c:738
__non_rtti_object *__thiscall __non_rtti_object_copy_ctor(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:251
int __thiscall type_info_opequals_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:426
void *__thiscall exception_scalar_dtor(exception *_this, unsigned int flags)
Definition: cpp.c:154
bad_typeid *__thiscall bad_typeid_copy_ctor(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:166
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:788
void *__thiscall bad_typeid_vector_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:216
const char *__thiscall type_info_raw_name(type_info *_this)
Definition: cpp.c:503
void __thiscall __non_rtti_object_dtor(__non_rtti_object *_this)
Definition: cpp.c:273
void *__thiscall __non_rtti_object_vector_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:295
int __thiscall type_info_opnot_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:437
bad_typeid *__thiscall bad_typeid_opequals(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:205
bad_cast *__thiscall bad_cast_ctor_charptr(bad_cast *_this, const char *name)
Definition: cpp.c:351
__non_rtti_object *__thiscall __non_rtti_object_opequals(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:283
unexpected_function CDECL _get_unexpected(void)
Definition: cpp.c:668
bad_cast *__thiscall bad_cast_opequals(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:380
bad_typeid *__thiscall bad_typeid_default_ctor(bad_typeid *_this)
Definition: cpp.c:186
exception __thiscall exception_ctor(exception *_this, const char **name)
Definition: cpp.c:105
exception __thiscall exception_opequals(exception *_this, const exception *rhs)
Definition: cpp.c:138
terminate_function CDECL _get_terminate(void)
Definition: cpp.c:637
bad_typeid *__thiscall bad_typeid_ctor(bad_typeid *_this, const char *name)
Definition: cpp.c:176
terminate_function CDECL set_terminate(terminate_function func)
Definition: cpp.c:625
static uintptr_t get_obj_locator_base(const rtti_object_locator *ptr)
Definition: cpp.c:68
__non_rtti_object *__thiscall __non_rtti_object_ctor(__non_rtti_object *_this, const char *name)
Definition: cpp.c:262
bad_cast *__thiscall bad_cast_default_ctor(bad_cast *_this)
Definition: cpp.c:361
exception __thiscall exception_ctor_noalloc(exception *_this, char **name, int noalloc)
Definition: cpp.c:115
const vtable_ptr __non_rtti_object_vtable
static const rtti_object_locator * get_obj_locator(void *cppobj)
Definition: cpp.c:62
#define CXX_EXCEPTION
Definition: cppexcept.h:34
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:169
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:31
static BOOL is_cxx_exception(EXCEPTION_RECORD *rec)
Definition: cppexcept.h:146
#define CREATE_EXCEPTION_OBJECT(exception_name)
Definition: cppexcept.h:300
#define CXX_EXCEPTION_PARAMS
Definition: cppexcept.h:89
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:177
#define CREATE_TYPE_INFO_VTABLE
Definition: cxx.h:492
#define __ASM_VTABLE(name, funcs)
Definition: cxx.h:49
static void * rtti_rva(unsigned int rva, uintptr_t base)
Definition: cxx.h:469
#define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name)
Definition: cxx.h:269
#define VTABLE_ADD_FUNC(name)
Definition: cxx.h:47
void(* vtable_ptr)(void)
Definition: cxx.h:322
#define DEFINE_RTTI_DATA0(name, off, mangled_name)
Definition: cxx.h:267
static uintptr_t rtti_rva_base(const void *ptr)
Definition: cxx.h:463
void CDECL DECLSPEC_HOTPATCH operator_delete(void *mem)
Definition: heap.c:177
#define __cdecl
Definition: corecrt.h:121
unsigned int uintptr_t
Definition: corecrt.h:185
void(__cdecl * _se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info)
Definition: eh.h:37
void(__cdecl * unexpected_function)(void)
Definition: eh.h:36
void(__cdecl * terminate_function)(void)
Definition: eh.h:34
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: ucrt_tls_sup.c:59
char *__cdecl __unDName(char *, const char *, int, malloc_func_t, free_func_t, unsigned short int)
Definition: undname.c:1783
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
#define ULONG_PTR
Definition: config.h:101
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
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
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 InterlockedCompareExchangePointer
Definition: interlocked.h:144
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
static PVOID ptr
Definition: dispmode.c:27
#define __thiscall
Definition: cpp.c:43
static void * vtable[]
Definition: typelib.c:1231
void __thiscall exception_dtor(exception *_this)
const char *__thiscall type_info_name_internal_method(type_info *_this, struct __type_info_node *node)
void *__thiscall exception_vector_dtor(exception *_this, unsigned int flags)
#define __non_rtti_object
Definition: msvc_fwd_decl.h:4
exception *__thiscall exception_copy_ctor(exception *_this, const exception *rhs)
const char *__thiscall exception_what(exception *_this)
#define bad_typeid
Definition: msvc_fwd_decl.h:3
#define bad_cast
Definition: msvc_fwd_decl.h:2
Definition: features.h:417
#define DEFINE_THISCALL_WRAPPER(func, args)
Definition: msvc-thiscall.c:2
static unsigned __int64 next
Definition: rand_nt.c:6
_CRTIMP int __cdecl _is_exception_typeof(const type_info &_Type, struct _EXCEPTION_POINTERS *_ExceptionPtr)
#define TRACE(s)
Definition: solgame.cpp:4
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
struct __type_info_node * next
Definition: cpp.c:44
void * memPtr
Definition: cpp.c:43
char mangled[128]
Definition: cxx.h:335
Definition: match.c:390
unsigned int type_info_table
Definition: cxx.h:454
unsigned int info[5]
Definition: cxx.h:446
unsigned int type_info
Definition: cxx.h:437
Definition: _hash_fun.h:40
Definition: name.c:39
unsigned int bases[10]
Definition: cxx.h:413
unsigned int attributes
Definition: cxx.h:408
int num_base_classes
Definition: cxx.h:406
unsigned int type_descriptor
Definition: cxx.h:405
this_ptr_offsets offsets
Definition: cxx.h:407
unsigned int base_classes
Definition: cxx.h:421
unsigned int type_hierarchy
Definition: cxx.h:430
int base_class_offset
Definition: cxx.h:427
unsigned int type_descriptor
Definition: cxx.h:429
int this_offset
Definition: cxx.h:341
int vbase_offset
Definition: cxx.h:343
int vbase_descr
Definition: cxx.h:342
char mangled[32]
Definition: cpp.c:41
char * name
Definition: cpp.c:40
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
#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
#define WINAPI
Definition: msvc.h:6
#define __ASM_BLOCK_END
Definition: asm.h:60
#define __ASM_BLOCK_BEGIN(name)
Definition: asm.h:59
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406
#define InterlockedFlushSList(SListHead)
Definition: rtlfuncs.h:3412
#define const
Definition: zconf.h:233