xref: /freebsd-src/contrib/libcxxrt/typeinfo.cc (revision 2d23488dac42e567e6d4de9ef1b0211c62f7e3e9)
194e3ee44SDavid Chisnall /*
294e3ee44SDavid Chisnall  * Copyright 2010-2012 PathScale, Inc. All rights reserved.
394e3ee44SDavid Chisnall  *
494e3ee44SDavid Chisnall  * Redistribution and use in source and binary forms, with or without
594e3ee44SDavid Chisnall  * modification, are permitted provided that the following conditions are met:
694e3ee44SDavid Chisnall  *
794e3ee44SDavid Chisnall  * 1. Redistributions of source code must retain the above copyright notice,
894e3ee44SDavid Chisnall  *    this list of conditions and the following disclaimer.
994e3ee44SDavid Chisnall  *
1094e3ee44SDavid Chisnall  * 2. Redistributions in binary form must reproduce the above copyright notice,
1194e3ee44SDavid Chisnall  *    this list of conditions and the following disclaimer in the documentation
1294e3ee44SDavid Chisnall  *    and/or other materials provided with the distribution.
1394e3ee44SDavid Chisnall  *
1494e3ee44SDavid Chisnall  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
1594e3ee44SDavid Chisnall  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1694e3ee44SDavid Chisnall  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1794e3ee44SDavid Chisnall  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
1894e3ee44SDavid Chisnall  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1994e3ee44SDavid Chisnall  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2094e3ee44SDavid Chisnall  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2194e3ee44SDavid Chisnall  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2294e3ee44SDavid Chisnall  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2394e3ee44SDavid Chisnall  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2494e3ee44SDavid Chisnall  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2594e3ee44SDavid Chisnall  */
2694e3ee44SDavid Chisnall 
277a984708SDavid Chisnall #include "typeinfo.h"
287a984708SDavid Chisnall #include <string.h>
297a984708SDavid Chisnall #include <stdlib.h>
307a984708SDavid Chisnall #include <stdio.h>
317a984708SDavid Chisnall 
327a984708SDavid Chisnall using std::type_info;
337a984708SDavid Chisnall 
~type_info()347a984708SDavid Chisnall type_info::~type_info() {}
357a984708SDavid Chisnall 
operator ==(const type_info & other) const367a984708SDavid Chisnall bool type_info::operator==(const type_info &other) const
377a984708SDavid Chisnall {
387a984708SDavid Chisnall 	return __type_name == other.__type_name;
397a984708SDavid Chisnall }
operator !=(const type_info & other) const407a984708SDavid Chisnall bool type_info::operator!=(const type_info &other) const
417a984708SDavid Chisnall {
424bf41ce2SDimitry Andric 	return __type_name != other.__type_name;
437a984708SDavid Chisnall }
before(const type_info & other) const447a984708SDavid Chisnall bool type_info::before(const type_info &other) const
457a984708SDavid Chisnall {
467a984708SDavid Chisnall 	return __type_name < other.__type_name;
477a984708SDavid Chisnall }
name() const487a984708SDavid Chisnall const char* type_info::name() const
497a984708SDavid Chisnall {
507a984708SDavid Chisnall 	return __type_name;
517a984708SDavid Chisnall }
type_info(const type_info & rhs)527a984708SDavid Chisnall type_info::type_info (const type_info& rhs)
537a984708SDavid Chisnall {
547a984708SDavid Chisnall 	__type_name = rhs.__type_name;
557a984708SDavid Chisnall }
operator =(const type_info & rhs)567a984708SDavid Chisnall type_info& type_info::operator= (const type_info& rhs)
577a984708SDavid Chisnall {
587a984708SDavid Chisnall 	return *new type_info(rhs);
597a984708SDavid Chisnall }
607a984708SDavid Chisnall 
~__fundamental_type_info()617a984708SDavid Chisnall ABI_NAMESPACE::__fundamental_type_info::~__fundamental_type_info() {}
~__array_type_info()627a984708SDavid Chisnall ABI_NAMESPACE::__array_type_info::~__array_type_info() {}
~__function_type_info()637a984708SDavid Chisnall ABI_NAMESPACE::__function_type_info::~__function_type_info() {}
~__enum_type_info()647a984708SDavid Chisnall ABI_NAMESPACE::__enum_type_info::~__enum_type_info() {}
~__class_type_info()657a984708SDavid Chisnall ABI_NAMESPACE::__class_type_info::~__class_type_info() {}
~__si_class_type_info()667a984708SDavid Chisnall ABI_NAMESPACE::__si_class_type_info::~__si_class_type_info() {}
~__vmi_class_type_info()677a984708SDavid Chisnall ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {}
~__pbase_type_info()687a984708SDavid Chisnall ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {}
~__pointer_type_info()697a984708SDavid Chisnall ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {}
~__pointer_to_member_type_info()707a984708SDavid Chisnall ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {}
717a984708SDavid Chisnall 
727a984708SDavid Chisnall // From libelftc
737a984708SDavid Chisnall extern "C" char    *__cxa_demangle_gnu3(const char *);
747a984708SDavid Chisnall 
__cxa_demangle(const char * mangled_name,char * buf,size_t * n,int * status)757a984708SDavid Chisnall extern "C" char* __cxa_demangle(const char* mangled_name,
767a984708SDavid Chisnall                                 char* buf,
777a984708SDavid Chisnall                                 size_t* n,
787a984708SDavid Chisnall                                 int* status)
797a984708SDavid Chisnall {
807a984708SDavid Chisnall 	// TODO: We should probably just be linking against libelf-tc, rather than
817a984708SDavid Chisnall 	// copying their code.  This requires them to do an actual release,
827a984708SDavid Chisnall 	// however, and for our changes to be pushed upstream.  We also need to
837a984708SDavid Chisnall 	// call a different demangling function here depending on the ABI (e.g.
847a984708SDavid Chisnall 	// ARM).
857a984708SDavid Chisnall 	char *demangled = __cxa_demangle_gnu3(mangled_name);
867a984708SDavid Chisnall 	if (NULL != demangled)
877a984708SDavid Chisnall 	{
887a984708SDavid Chisnall 		size_t len = strlen(demangled);
89*2d23488dSDimitry Andric 		if (!buf || (*n < len+1))
900f9eee39SDavid Chisnall 		{
91f2dc4184SDimitry Andric 			buf = static_cast<char*>(realloc(buf, len+1));
920f9eee39SDavid Chisnall 		}
937a984708SDavid Chisnall 		if (0 != buf)
947a984708SDavid Chisnall 		{
957a984708SDavid Chisnall 			memcpy(buf, demangled, len);
967a984708SDavid Chisnall 			buf[len] = 0;
9794e3ee44SDavid Chisnall 			if (n)
9894e3ee44SDavid Chisnall 			{
997a984708SDavid Chisnall 				*n = len;
10094e3ee44SDavid Chisnall 			}
10194e3ee44SDavid Chisnall 			if (status)
10294e3ee44SDavid Chisnall 			{
1037a984708SDavid Chisnall 				*status = 0;
1047a984708SDavid Chisnall 			}
10594e3ee44SDavid Chisnall 		}
1067a984708SDavid Chisnall 		else
1077a984708SDavid Chisnall 		{
10894e3ee44SDavid Chisnall 			if (status)
10994e3ee44SDavid Chisnall 			{
1107a984708SDavid Chisnall 				*status = -1;
1117a984708SDavid Chisnall 			}
11294e3ee44SDavid Chisnall 		}
1137a984708SDavid Chisnall 		free(demangled);
1147a984708SDavid Chisnall 	}
1157a984708SDavid Chisnall 	else
1167a984708SDavid Chisnall 	{
11794e3ee44SDavid Chisnall 		if (status)
11894e3ee44SDavid Chisnall 		{
1197a984708SDavid Chisnall 			*status = -2;
12094e3ee44SDavid Chisnall 		}
1217a984708SDavid Chisnall 		return NULL;
1227a984708SDavid Chisnall 	}
1237a984708SDavid Chisnall 	return buf;
1247a984708SDavid Chisnall }
125