OSDN Git Service

4f5ce4960efafd0b6b2ac8f8f7b763cbdc7a8e9f
[pf3gnuchains/gcc-fork.git] / gcc / cp / vec.cc
1 // new abi support -*- C++ -*-
2 // Copyright (C) 2000
3 // Free Software Foundation, Inc.
4 // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
5 // 
6 // GNU CC is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // GNU CC is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License
17 // along with GNU CC; see the file COPYING.  If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330,
19 // Boston, MA 02111-1307, USA. 
20
21 // As a special exception, if you link this library with other files,
22 // some of which are compiled with GCC, to produce an executable,
23 // this library does not by itself cause the resulting executable
24 // to be covered by the GNU General Public License.
25 // This exception does not however invalidate any other reasons why
26 // the executable file might be covered by the GNU General Public License.
27
28 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
29 #include <cxxabi.h>
30 #include <new>
31 #include <exception>
32
33 // Exception handling hook, to mark current exception as not caught --
34 // generally because we're about to rethrow it after some cleanup.
35 extern "C" void __uncatch_exception (void);
36
37 namespace __cxxabiv1
38 {
39
40 /* allocate and construct array */
41 void *
42 __cxa_vec_new (size_t element_count,
43                size_t element_size,
44                size_t padding_size,
45                void (*constructor) (void *),
46                void (*destructor) (void *))
47 {
48   size_t size = element_count * element_size + padding_size;
49   char *base = static_cast <char *> (operator new[] (size));
50   
51   if (padding_size)
52     {
53       base += padding_size;
54       reinterpret_cast <size_t *> (base)[-1] = element_count;
55     }
56   try
57     {
58       __cxa_vec_ctor (base, element_count, element_size,
59                       constructor, destructor);
60     }
61   catch (...)
62     {
63       // operator delete [] cannot throw, so no need to protect it
64       operator delete[] (base - padding_size);
65       throw;
66     }
67   return base;
68 }
69
70 /* construct array */
71 void
72 __cxa_vec_ctor (void *array_address,
73                 size_t element_count,
74                 size_t element_size,
75                 void (*constructor) (void *),
76                 void (*destructor) (void *))
77 {
78   size_t ix = 0;
79   char *ptr = static_cast <char *> (array_address);
80   
81   try
82     {
83       if (constructor)
84         for (; ix != element_count; ix++, ptr += element_size)
85           constructor (ptr);
86     }
87   catch (...)
88     {
89       __uncatch_exception ();
90       __cxa_vec_dtor (array_address, ix, element_size, destructor);
91       throw;
92     }
93 }
94
95 /* destruct array */
96 void
97 __cxa_vec_dtor (void *array_address,
98                 size_t element_count,
99                 size_t element_size,
100                 void (*destructor) (void *))
101 {
102   if (destructor)
103     {
104       char *ptr = static_cast <char *> (array_address);
105       size_t ix = element_count;
106       bool unwinding = std::uncaught_exception ();
107       
108       ptr += element_count * element_size;
109       
110       try
111         {
112           while (ix--)
113             {
114               ptr -= element_size;
115               destructor (ptr);
116             }
117         }
118       catch (...)
119         {
120           if (unwinding)
121             // [except.ctor]/3 If a destructor called during stack unwinding
122             // exists with an exception, terminate is called.
123             std::terminate ();
124           __uncatch_exception ();
125           __cxa_vec_dtor (array_address, ix, element_size, destructor);
126           throw;
127         }
128     }
129 }
130
131 /* destruct and release array */
132 void
133 __cxa_vec_delete (void *array_address,
134                   size_t element_size,
135                   size_t padding_size,
136                   void (*destructor) (void *))
137 {
138   char *base = static_cast <char *> (array_address);
139   
140   if (padding_size)
141     {
142       size_t element_count = reinterpret_cast <size_t *> (base)[-1];
143       base -= padding_size;
144       try
145         {
146           __cxa_vec_dtor (array_address, element_count, element_size,
147                           destructor);
148         }
149       catch (...)
150         {
151           // operator delete [] cannot throw, so no need to protect it
152           operator delete[] (base);
153           throw;
154         }
155     }
156   operator delete[] (base);
157 }
158
159 } // namespace __cxxabiv1
160
161 #endif // defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100