ReactOS 0.4.16-dev-2104-gb84fa49
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;
41 struct __type_info_node* next;
42};
43
44typedef exception bad_cast;
45typedef exception bad_typeid;
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 */
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 */
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 */
212{
213 return bad_typeid_ctor( _this, "bad typeid" );
214}
215
216/******************************************************************
217 * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
218 */
221{
222 TRACE("(%p)\n", _this);
223 exception_dtor(_this);
224}
225
226/******************************************************************
227 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
228 */
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 */
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 */
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 */
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 */
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 */
299{
300 TRACE("(%p)\n", _this);
301 bad_typeid_dtor(_this);
302}
303
304/******************************************************************
305 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
306 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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{
1145 EXCEPTION_RECORD *rec;
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 */
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
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 */
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
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 {
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);
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 {
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 */
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
r l[0]
Definition: byte_order.h:168
FxCollectionEntry * Next(VOID)
#define 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
unexpected_function CDECL set_unexpected(unexpected_function func)
Definition: cpp.c:654
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:890
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:708
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:865
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:676
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:698
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:734
__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:784
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:666
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:636
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:624
__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
void __cdecl __ExceptionPtrCreate(exception_ptr *)
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:137
#define CXX_FRAME_MAGIC_VC7
Definition: cppexcept.h:32
static void call_dtor(void *func, void *this)
Definition: cppexcept.h:207
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:31
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:138
static void call_copy_ctor(void *func, void *this, void *src, int has_vbase)
Definition: cppexcept.h:200
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:33
void __cdecl __ExceptionPtrDestroy(exception_ptr *)
#define CREATE_EXCEPTION_OBJECT(exception_name)
Definition: cppexcept.h:300
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
#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
void CDECL DECLSPEC_HOTPATCH operator_delete(void *mem)
Definition: heap.c:177
#define __cdecl
Definition: corecrt.h:121
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: thread.c:45
char *__cdecl __unDName(char *, const char *, int, malloc_func_t, free_func_t, unsigned short int)
Definition: undname.c:1783
unsigned char
Definition: typeof.h:29
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
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 InterlockedCompareExchangePointer
Definition: interlocked.h:144
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
#define __thiscall
Definition: cpp.c:43
static void * vtable[]
Definition: typelib.c:1231
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
void __thiscall exception_dtor(exception *_this)
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 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
_CRTIMP int __cdecl _is_exception_typeof(const type_info &_Type, struct _EXCEPTION_POINTERS *_ExceptionPtr)
void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
Definition: cpp.c:1245
#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
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 size
Definition: cxx.h:439
unsigned int type_info
Definition: cxx.h:437
this_ptr_offsets offsets
Definition: cxx.h:438
UINT flags
Definition: cxx.h:436
unsigned int copy_ctor
Definition: cxx.h:440
LONG * ref
Definition: cppexcept.h:157
int * ref
Definition: cpp.c:1146
EXCEPTION_RECORD * rec
Definition: cppexcept.h:156
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
unsigned int signature
Definition: cxx.h:426
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 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
#define WINAPI
Definition: msvc.h: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
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406
#define InterlockedFlushSList(SListHead)
Definition: rtlfuncs.h:3412
#define const
Definition: zconf.h:233