]>
Commit | Line | Data |
---|---|---|
52a11cbf | 1 | // -*- C++ -*- Exception handling routines for catching. |
c3862806 | 2 | // Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. |
52a11cbf | 3 | // |
cbecceb9 | 4 | // This file is part of GCC. |
52a11cbf | 5 | // |
cbecceb9 | 6 | // GCC is free software; you can redistribute it and/or modify |
52a11cbf RH |
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 | // | |
cbecceb9 | 11 | // GCC is distributed in the hope that it will be useful, |
52a11cbf RH |
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 | |
cbecceb9 | 17 | // along with GCC; see the file COPYING. If not, write to |
52a11cbf RH |
18 | // the Free Software Foundation, 59 Temple Place - Suite 330, |
19 | // Boston, MA 02111-1307, USA. | |
20 | ||
21 | // As a special exception, you may use this file as part of a free software | |
22 | // library without restriction. Specifically, if other files instantiate | |
23 | // templates or use macros or inline functions from this file, or you compile | |
24 | // this file and link it with other files to produce an executable, this | |
25 | // file does not by itself cause the resulting executable to be covered by | |
26 | // the GNU General Public License. This exception does not however | |
27 | // invalidate any other reasons why the executable file might be covered by | |
28 | // the GNU General Public License. | |
29 | ||
30 | ||
31 | #include <cstdlib> | |
32 | #include "unwind-cxx.h" | |
33 | ||
34 | using namespace __cxxabiv1; | |
35 | ||
36 | ||
37 | extern "C" void * | |
563ae04f | 38 | __cxa_begin_catch (void *exc_obj_in) throw() |
52a11cbf | 39 | { |
74a3070f JM |
40 | _Unwind_Exception *exceptionObject |
41 | = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); | |
52a11cbf RH |
42 | __cxa_eh_globals *globals = __cxa_get_globals (); |
43 | __cxa_exception *prev = globals->caughtExceptions; | |
a944ceb9 RH |
44 | __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); |
45 | ||
46 | // Foreign exceptions can't be stacked here. If the exception stack is | |
47 | // empty, then fine. Otherwise we really have no choice but to terminate. | |
48 | // Note that this use of "header" is a lie. It's fine so long as we only | |
49 | // examine header->unwindHeader though. | |
50 | if (header->unwindHeader.exception_class != __gxx_exception_class) | |
51 | { | |
52 | if (prev != 0) | |
53 | std::terminate (); | |
54 | ||
55 | // Remember for end_catch and rethrow. | |
56 | globals->caughtExceptions = header; | |
57 | ||
58 | // ??? No sensible value to return; we don't know what the | |
59 | // object is, much less where it is in relation to the header. | |
60 | return 0; | |
61 | } | |
52a11cbf | 62 | |
a944ceb9 | 63 | int count = header->handlerCount; |
52a11cbf RH |
64 | if (count < 0) |
65 | // This exception was rethrown from an immediately enclosing region. | |
66 | count = -count + 1; | |
67 | else | |
c3862806 RH |
68 | { |
69 | count += 1; | |
70 | globals->uncaughtExceptions -= 1; | |
71 | } | |
52a11cbf RH |
72 | header->handlerCount = count; |
73 | ||
52a11cbf RH |
74 | if (header != prev) |
75 | { | |
76 | header->nextException = prev; | |
77 | globals->caughtExceptions = header; | |
78 | } | |
79 | ||
80 | return header->adjustedPtr; | |
81 | } | |
82 | ||
83 | ||
84 | extern "C" void | |
85 | __cxa_end_catch () | |
86 | { | |
87 | __cxa_eh_globals *globals = __cxa_get_globals_fast (); | |
88 | __cxa_exception *header = globals->caughtExceptions; | |
52a11cbf | 89 | |
a944ceb9 RH |
90 | // A rethrow of a foreign exception will be removed from the |
91 | // the exception stack immediately by __cxa_rethrow. | |
92 | if (!header) | |
93 | return; | |
94 | ||
95 | // A foreign exception couldn't have been stacked (see above), | |
96 | // so by definition processing must be complete. | |
97 | if (header->unwindHeader.exception_class != __gxx_exception_class) | |
98 | { | |
99 | globals->caughtExceptions = 0; | |
100 | _Unwind_DeleteException (&header->unwindHeader); | |
101 | return; | |
102 | } | |
103 | ||
104 | int count = header->handlerCount; | |
52a11cbf RH |
105 | if (count < 0) |
106 | { | |
107 | // This exception was rethrown. Decrement the (inverted) catch | |
108 | // count and remove it from the chain when it reaches zero. | |
109 | if (++count == 0) | |
110 | { | |
111 | globals->uncaughtExceptions += 1; | |
112 | globals->caughtExceptions = header->nextException; | |
113 | } | |
114 | } | |
115 | else if (--count == 0) | |
116 | { | |
117 | // Handling for this exception is complete. Destroy the object. | |
118 | globals->caughtExceptions = header->nextException; | |
119 | _Unwind_DeleteException (&header->unwindHeader); | |
120 | return; | |
121 | } | |
122 | else if (count < 0) | |
123 | // A bug in the exception handling library or compiler. | |
a944ceb9 | 124 | std::terminate (); |
52a11cbf RH |
125 | |
126 | header->handlerCount = count; | |
127 | } | |
128 | ||
129 | ||
130 | bool | |
131 | std::uncaught_exception() throw() | |
132 | { | |
133 | __cxa_eh_globals *globals = __cxa_get_globals (); | |
134 | return globals->uncaughtExceptions != 0; | |
135 | } |