X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Flibsupc%2B%2B%2Fvec.cc;fp=libstdc%2B%2B-v3%2Flibsupc%2B%2B%2Fvec.cc;h=886e6fc99c849fc978fe881711a35d78eaebed25;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=557fd039432ca9bd8aeb23cabd99acd757f926c6;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index 557fd039..886e6fc9 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -1,32 +1,27 @@ // New abi Support -*- C++ -*- -// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2003, 2004, 2009 Free Software Foundation, Inc. // -// This file is part of GNU CC. +// This file is part of GCC. // -// GNU CC is free software; you can redistribute it and/or modify +// GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or (at your option) +// the Free Software Foundation; either version 3, or (at your option) // any later version. -// GNU CC is distributed in the hope that it will be useful, +// GCC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// You should have received a copy of the GNU General Public License -// along with GNU CC; see the file COPYING. If not, write to -// the Free Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . // Written by Nathan Sidwell, Codesourcery LLC, @@ -42,13 +37,19 @@ namespace __cxxabiv1 { struct uncatch_exception { - uncatch_exception (); + uncatch_exception(); ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } - __cxa_exception *p; + __cxa_exception* p; + + private: + uncatch_exception& + operator=(const uncatch_exception&); + + uncatch_exception(const uncatch_exception&); }; - uncatch_exception::uncatch_exception () + uncatch_exception::uncatch_exception() : p(0) { __cxa_eh_globals *globals = __cxa_get_globals_fast (); @@ -64,8 +65,8 @@ namespace __cxxabiv1 __cxa_vec_new(std::size_t element_count, std::size_t element_size, std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *)) + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) { return __cxa_vec_new2(element_count, element_size, padding_size, constructor, destructor, @@ -76,18 +77,23 @@ namespace __cxxabiv1 __cxa_vec_new2(std::size_t element_count, std::size_t element_size, std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *), + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, void *(*alloc) (std::size_t), void (*dealloc) (void *)) { std::size_t size = element_count * element_size + padding_size; char *base = static_cast (alloc (size)); - + if (!base) + return base; + if (padding_size) { base += padding_size; reinterpret_cast (base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast (base)[-2] = element_size; +#endif } try { @@ -109,18 +115,23 @@ namespace __cxxabiv1 __cxa_vec_new3(std::size_t element_count, std::size_t element_size, std::size_t padding_size, - void (*constructor) (void *), - void (*destructor) (void *), + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, void *(*alloc) (std::size_t), void (*dealloc) (void *, std::size_t)) { std::size_t size = element_count * element_size + padding_size; char *base = static_cast(alloc (size)); + if (!base) + return base; if (padding_size) { base += padding_size; reinterpret_cast(base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast (base)[-2] = element_size; +#endif } try { @@ -139,12 +150,12 @@ namespace __cxxabiv1 } // Construct array. - extern "C" void + extern "C" __cxa_vec_ctor_return_type __cxa_vec_ctor(void *array_address, std::size_t element_count, std::size_t element_size, - void (*constructor) (void *), - void (*destructor) (void *)) + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) { std::size_t ix = 0; char *ptr = static_cast(array_address); @@ -163,16 +174,17 @@ namespace __cxxabiv1 } __throw_exception_again; } + _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address); } // Construct an array by copying. - extern "C" void + extern "C" __cxa_vec_ctor_return_type __cxa_vec_cctor(void *dest_array, void *src_array, std::size_t element_count, std::size_t element_size, - void (*constructor) (void *, void *), - void (*destructor) (void *)) + __cxa_cdtor_return_type (*constructor) (void *, void *), + __cxa_cdtor_type destructor) { std::size_t ix = 0; char *dest_ptr = static_cast(dest_array); @@ -193,6 +205,7 @@ namespace __cxxabiv1 } __throw_exception_again; } + _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array); } // Destruct array. @@ -200,7 +213,7 @@ namespace __cxxabiv1 __cxa_vec_dtor(void *array_address, std::size_t element_count, std::size_t element_size, - void (*destructor) (void *)) + __cxa_cdtor_type destructor) { if (destructor) { @@ -235,7 +248,7 @@ namespace __cxxabiv1 __cxa_vec_cleanup(void *array_address, std::size_t element_count, std::size_t element_size, - void (*destructor) (void *)) + __cxa_cdtor_type destructor) { if (destructor) { @@ -264,7 +277,7 @@ namespace __cxxabiv1 __cxa_vec_delete(void *array_address, std::size_t element_size, std::size_t padding_size, - void (*destructor) (void *)) + __cxa_cdtor_type destructor) { __cxa_vec_delete2(array_address, element_size, padding_size, destructor, @@ -275,10 +288,13 @@ namespace __cxxabiv1 __cxa_vec_delete2(void *array_address, std::size_t element_size, std::size_t padding_size, - void (*destructor) (void *), + __cxa_cdtor_type destructor, void (*dealloc) (void *)) { - char *base = static_cast(array_address); + if (!array_address) + return; + + char* base = static_cast(array_address); if (padding_size) { @@ -305,12 +321,15 @@ namespace __cxxabiv1 __cxa_vec_delete3(void *array_address, std::size_t element_size, std::size_t padding_size, - void (*destructor) (void *), + __cxa_cdtor_type destructor, void (*dealloc) (void *, std::size_t)) { - char *base = static_cast (array_address); + if (!array_address) + return; + + char* base = static_cast (array_address); std::size_t size = 0; - + if (padding_size) { std::size_t element_count = reinterpret_cast (base)[-1]; @@ -334,3 +353,159 @@ namespace __cxxabiv1 } } // namespace __cxxabiv1 +#if defined(__arm__) && defined(__ARM_EABI__) + +// The ARM C++ ABI requires that the library provide these additional +// helper functions. There are placed in this file, despite being +// architecture-specifier, so that the compiler can inline the __cxa +// functions into these functions as appropriate. + +namespace __aeabiv1 +{ + extern "C" void * + __aeabi_vec_ctor_nocookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_ctor (array_address, element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_ctor_cookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + if (array_address == NULL) + return NULL; + + array_address = reinterpret_cast(array_address) + 2; + reinterpret_cast(array_address)[-2] = element_size; + reinterpret_cast(array_address)[-1] = element_count; + return abi::__cxa_vec_ctor (array_address, + element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_cctor_nocookie_nodtor (void *dest_array, + void *src_array, + std::size_t element_size, + std::size_t element_count, + void *(*constructor) (void *, void *)) + { + return abi::__cxa_vec_cctor (dest_array, src_array, + element_count, element_size, + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_noctor (std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + /*constructor=*/NULL, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_new_nocookie (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new (element_count, element_size, 0, constructor, + NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_nodtor (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie(std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor, + abi::__cxa_cdtor_type destructor) + { + return abi::__cxa_vec_new (element_count, element_size, + 2 * sizeof (std::size_t), + constructor, destructor); + } + + + extern "C" void * + __aeabi_vec_dtor (void *array_address, + abi::__cxa_cdtor_type destructor, + std::size_t element_size, + std::size_t element_count) + { + abi::__cxa_vec_dtor (array_address, element_count, element_size, + destructor); + return reinterpret_cast (array_address) - 2; + } + + extern "C" void * + __aeabi_vec_dtor_cookie (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return NULL; + + abi::__cxa_vec_dtor (array_address, + reinterpret_cast(array_address)[-1], + reinterpret_cast(array_address)[-2], + destructor); + return reinterpret_cast (array_address) - 2; + } + + + extern "C" void + __aeabi_vec_delete (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return; + + abi::__cxa_vec_delete (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + destructor); + } + + extern "C" void + __aeabi_vec_delete3 (void *array_address, + abi::__cxa_cdtor_type destructor, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + destructor, dealloc); + } + + extern "C" void + __aeabi_vec_delete3_nodtor (void *array_address, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast(array_address)[-2], + 2 * sizeof (std::size_t), + /*destructor=*/NULL, dealloc); + } +} // namespace __aeabiv1 + +#endif // defined(__arm__) && defined(__ARM_EABI__)