ReactOS 0.4.16-dev-822-gbcedb53
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 || defined(__UCRTSUPPORT__)
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 {
1067 }
1068 __ENDTRY
1069
1070 if(ret == -1)
1071 terminate();
1072 return ret;
1073}
1074#else
1076{
1077 int ret = -1;
1078
1079 TRACE("(%p %p)\n", ti, ep);
1080
1081 __TRY
1082 {
1084
1085 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 &&
1089 {
1092 int i;
1093
1094 for (i=0; i<tit->count; i++) {
1095 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]);
1096 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info);
1097 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
1098 {
1099 ret = 1;
1100 break;
1101 }
1102 }
1103
1104 if (i == tit->count)
1105 ret = 0;
1106 }
1107 }
1109 {
1110 }
1111 __ENDTRY
1112
1113 if(ret == -1)
1114 terminate();
1115 return ret;
1116}
1117#endif
1118
1119/*********************************************************************
1120 * __clean_type_info_names_internal (MSVCR80.@)
1121 */
1122void CDECL __clean_type_info_names_internal(void *p)
1123{
1124 FIXME("(%p) stub\n", p);
1125}
1126
1127/*********************************************************************
1128 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
1129 */
1130const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node);
1131DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8)
1132const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
1133{
1134 static int once;
1135 if (node && !once++) FIXME("type_info_node parameter ignored\n");
1136
1137 return type_info_name(_this);
1138}
1139
1140#endif /* _MSVCR_VER >= 80 */
1141
1142/* std::exception_ptr class helpers */
1143typedef struct
1144{
1146 int *ref; /* not binary compatible with native msvcr100 */
1148
1149#if _MSVCR_VER >= 100
1150
1151/*********************************************************************
1152 * ?__ExceptionPtrCreate@@YAXPAX@Z
1153 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1154 */
1155void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1156{
1157 TRACE("(%p)\n", ep);
1158
1159 ep->rec = NULL;
1160 ep->ref = NULL;
1161}
1162
1163#ifdef __ASM_USE_THISCALL_WRAPPER
1164extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1165
1166__ASM_GLOBAL_FUNC( call_dtor,
1167 "movl 12(%esp),%ecx\n\t"
1168 "call *8(%esp)\n\t"
1169 "ret" );
1170#elif __x86_64__
1171static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1172{
1173 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1174 void (__cdecl *func)(void*) = (void*)(base + dtor);
1175 func(object);
1176}
1177#else
1178#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1179#endif
1180
1181/*********************************************************************
1182 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1183 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1184 */
1185void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1186{
1187 TRACE("(%p)\n", ep);
1188
1189 if (!ep->rec)
1190 return;
1191
1192 if (!InterlockedDecrement(ep->ref))
1193 {
1194 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1195 {
1196 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1197 void *obj = (void*)ep->rec->ExceptionInformation[1];
1198
1199 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1201 }
1202
1203 HeapFree(GetProcessHeap(), 0, ep->rec);
1204 HeapFree(GetProcessHeap(), 0, ep->ref);
1205 }
1206}
1207
1208/*********************************************************************
1209 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1210 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1211 */
1212void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1213{
1214 TRACE("(%p %p)\n", ep, copy);
1215
1216 /* don't destroy object stored in ep */
1217 *ep = *copy;
1218 if (ep->ref)
1220}
1221
1222/*********************************************************************
1223 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1224 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1225 */
1226void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1227{
1228 TRACE("(%p %p)\n", ep, assign);
1229
1230 /* don't destroy object stored in ep */
1231 if (ep->ref)
1233
1234 *ep = *assign;
1235 if (ep->ref)
1237}
1238
1239#endif /* _MSVCR_VER >= 100 */
1240
1241/*********************************************************************
1242 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1243 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1244 */
1246{
1247 TRACE("(%p)\n", ep);
1248
1249 if (!ep->rec)
1250 {
1251 static const char *exception_msg = "bad exception";
1252 exception e;
1253
1254 exception_ctor(&e, &exception_msg);
1255 _CxxThrowException(&e, &exception_exception_type);
1256 return;
1257 }
1258
1261}
1262
1263#if _MSVCR_VER >= 100
1264
1265#ifdef __i386__
1266extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
1267#else
1268static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
1269{
1270 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
1271 if (has_vbase)
1272 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
1273 else
1274 ((void (__cdecl*)(void*, void*))func)(this, src);
1275}
1276#endif
1277
1278/*********************************************************************
1279 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1280 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1281 */
1282#ifndef __x86_64__
1283void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1284{
1285 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1286
1287 TRACE("(%p)\n", ep);
1288
1289 if (!rec)
1290 {
1291 ep->rec = NULL;
1292 ep->ref = NULL;
1293 return;
1294 }
1295
1296 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1297 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1298
1299 *ep->rec = *rec;
1300 *ep->ref = 1;
1301
1302 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1303 {
1304 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1305 const cxx_type_info *ti;
1306 void **data, *obj;
1307
1308 ti = et->type_info_table->info[0];
1309 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1310
1311 obj = (void*)ep->rec->ExceptionInformation[1];
1312 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1313 {
1314 memcpy(data, obj, ti->size);
1315 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1316 }
1317 else if (ti->copy_ctor)
1318 {
1319 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1320 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1321 }
1322 else
1323 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1325 }
1326 return;
1327}
1328#else
1329void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1330{
1331 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1332
1333 TRACE("(%p)\n", ep);
1334
1335 if (!rec)
1336 {
1337 ep->rec = NULL;
1338 ep->ref = NULL;
1339 return;
1340 }
1341
1342 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1343 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1344
1345 *ep->rec = *rec;
1346 *ep->ref = 1;
1347
1348 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1349 {
1350 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1351 const cxx_type_info *ti;
1352 void **data, *obj;
1353 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1354
1355 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1356 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1357
1358 obj = (void*)ep->rec->ExceptionInformation[1];
1359 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1360 {
1361 memcpy(data, obj, ti->size);
1362 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1363 }
1364 else if (ti->copy_ctor)
1365 {
1366 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1367 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1368 }
1369 else
1370 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1372 }
1373 return;
1374}
1375#endif
1376
1377#endif /* _MSVCR_VER >= 100 */
1378
1379#if _MSVCR_VER >= 110
1380/*********************************************************************
1381 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1382 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1383 */
1384bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1385{
1386 return !!ep->rec;
1387}
1388#endif
1389
1390#if _MSVCR_VER >= 100
1391
1392/*********************************************************************
1393 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1394 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1395 */
1396#ifndef __x86_64__
1397void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1398 exception *object, const cxx_exception_type *type)
1399{
1400 const cxx_type_info *ti;
1401 void **data;
1402
1403 __ExceptionPtrDestroy(ep);
1404
1405 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1406 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1407 *ep->ref = 1;
1408
1409 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1412 ep->rec->NumberParameters = 3;
1415
1416 ti = type->type_info_table->info[0];
1417 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1418 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1419 {
1420 memcpy(data, object, ti->size);
1421 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1422 }
1423 else if (ti->copy_ctor)
1424 {
1425 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1427 }
1428 else
1429 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1431}
1432#else
1433void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1434 exception *object, const cxx_exception_type *type)
1435{
1436 const cxx_type_info *ti;
1437 void **data;
1438 char *base;
1439
1440 RtlPcToFileHeader((void*)type, (void**)&base);
1441 __ExceptionPtrDestroy(ep);
1442
1443 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1444 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1445 *ep->ref = 1;
1446
1447 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1450 ep->rec->NumberParameters = 4;
1454
1455 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
1456 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1457 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1458 {
1459 memcpy(data, object, ti->size);
1460 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1461 }
1462 else if (ti->copy_ctor)
1463 {
1464 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1466 }
1467 else
1468 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1470}
1471#endif
1472
1473bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
1474{
1475 return ep1->rec == ep2->rec;
1476}
1477
1478#endif /* _MSVCR_VER >= 100 */
1479
1480#if _MSVCR_VER >= 80 || defined(__UCRTSUPPORT__)
1481void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
1482{
1483 return get_this_pointer(off, obj);
1484}
1485#endif
1486
1487#if _MSVCR_VER >= 140 || defined(__UCRTSUPPORT__)
1488
1489typedef struct
1490{
1491 char *name;
1492 char mangled[1];
1493} type_info140;
1494
1495typedef struct
1496{
1498 char name[1];
1499} type_info_entry;
1500
1501static void* CDECL type_info_entry_malloc(size_t size)
1502{
1503 type_info_entry *ret = malloc(FIELD_OFFSET(type_info_entry, name) + size);
1504 return ret->name;
1505}
1506
1507static void CDECL type_info_entry_free(void *ptr)
1508{
1509 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
1510 free(ptr);
1511}
1512
1513/******************************************************************
1514 * __std_type_info_compare (UCRTBASE.@)
1515 */
1516int CDECL __std_type_info_compare(const type_info140 *l, const type_info140 *r)
1517{
1518 int ret;
1519
1520 if (l == r) ret = 0;
1521 else ret = strcmp(l->mangled + 1, r->mangled + 1);
1522 TRACE("(%p %p) returning %d\n", l, r, ret);
1523 return ret;
1524}
1525
1526/******************************************************************
1527 * __std_type_info_name (UCRTBASE.@)
1528 */
1529const char* CDECL __std_type_info_name(type_info140 *ti, SLIST_HEADER *header)
1530{
1531 if (!ti->name)
1532 {
1533 char* name = __unDName(0, ti->mangled + 1, 0,
1534 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
1535 if (name)
1536 {
1537 unsigned int len = strlen(name);
1538
1539 while (len && name[--len] == ' ')
1540 name[len] = '\0';
1541
1542 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
1543 {
1544 type_info_entry_free(name);
1545 }
1546 else
1547 {
1548 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
1550 }
1551 }
1552 }
1553 TRACE("(%p) returning %s\n", ti, ti->name);
1554 return ti->name;
1555}
1556
1557/******************************************************************
1558 * __std_type_info_destroy_list (UCRTBASE.@)
1559 */
1560void CDECL __std_type_info_destroy_list(SLIST_HEADER *header)
1561{
1562 SLIST_ENTRY *cur, *next;
1563
1564 TRACE("(%p)\n", header);
1565
1567 {
1568 next = cur->Next;
1569 free(cur);
1570 }
1571}
1572
1573/******************************************************************
1574 * __std_type_info_hash (UCRTBASE.@)
1575 */
1576size_t CDECL __std_type_info_hash(const type_info140 *ti)
1577{
1578 size_t hash, fnv_prime;
1579 const char *p;
1580
1581#ifdef _WIN64
1582 hash = 0xcbf29ce484222325;
1583 fnv_prime = 0x100000001b3;
1584#else
1585 hash = 0x811c9dc5;
1586 fnv_prime = 0x1000193;
1587#endif
1588
1589 TRACE("(%p)->%s\n", ti, ti->mangled);
1590
1591 for(p = ti->mangled+1; *p; p++) {
1592 hash ^= *p;
1593 hash *= fnv_prime;
1594 }
1595
1596#ifdef _WIN64
1597 hash ^= hash >> 32;
1598#endif
1599
1600 return hash;
1601}
1602
1603#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)
void(__CRTDECL * terminate_function)(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
void _cdecl operator_delete(void *mem)
Definition: stubs.c:19
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
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 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)
#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:866
#define __thiscall
Definition: cpp.c:43
void(* vtable_ptr)(void)
Definition: cpp.c:23
static unsigned int
Definition: cpp.c:58
static vtable_ptr * get_vtable(void *obj)
Definition: cpp.c:861
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:14
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:1245
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
#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:1145
int * ref
Definition: cpp.c:1146
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