OSDN Git Service

(__objc_register_instance_methods_to_class): New function.
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 92-95, 1996 Free Software Foundation, Inc.
3    Contributed by Mike Stump <mrs@cygnus.com>.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC 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
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 /* An exception is an event that can be signaled from within a
24    function. This event can then be "caught" or "trapped" by the
25    callers of this function. This potentially allows program flow to
26    be transferred to any arbitrary code assocated with a function call
27    several levels up the stack.
28
29    The intended use for this mechanism is for signaling "exceptional
30    events" in an out-of-band fashion, hence its name. The C++ language
31    (and many other OO-styled or functional languages) practically
32    requires such a mechanism, as otherwise it becomes very difficult
33    or even impossible to signal failure conditions in complex
34    situations.  The traditional C++ example is when an error occurs in
35    the process of constructing an object; without such a mechanism, it
36    is impossible to signal that the error occurs without adding global
37    state variables and error checks around every object construction.
38
39    The act of causing this event to occur is referred to as "throwing
40    an exception". (Alternate terms include "raising an exception" or
41    "signaling an exception".) The term "throw" is used because control
42    is returned to the callers of the function that is signaling the
43    exception, and thus there is the concept of "throwing" the
44    exception up the call stack.
45
46    There are two major codegen options for exception handling.  The
47    flag -fsjlj-exceptions can be used to select the setjmp/longjmp
48    approach, which is the default.  -fnosjlj-exceptions can be used to
49    get the PC range table approach.  While this is a compile time
50    flag, an entire application must be compiled with the same codegen
51    option.  The first is a PC range table approach, the second is a
52    setjmp/longjmp based scheme.  We will first discuss the PC range
53    table approach, after that, we will discuss the setjmp/longjmp
54    based approach.
55
56    It is appropriate to speak of the "context of a throw". This
57    context refers to the address where the exception is thrown from,
58    and is used to determine which exception region will handle the
59    exception.
60
61    Regions of code within a function can be marked such that if it
62    contains the context of a throw, control will be passed to a
63    designated "exception handler". These areas are known as "exception
64    regions".  Exception regions cannot overlap, but they can be nested
65    to any arbitrary depth. Also, exception regions cannot cross
66    function boundaries.
67
68    Exception handlers can either be specified by the user (which we
69    will call a "user-defined handler") or generated by the compiler
70    (which we will designate as a "cleanup"). Cleanups are used to
71    perform tasks such as destruction of objects allocated on the
72    stack.
73
74    In the current implementaion, cleanups are handled by allocating an
75    exception region for the area that the cleanup is designated for,
76    and the handler for the region performs the cleanup and then
77    rethrows the exception to the outer exception region. From the
78    standpoint of the current implementation, there is little
79    distinction made between a cleanup and a user-defined handler, and
80    the phrase "exception handler" can be used to refer to either one
81    equally well. (The section "Future Directions" below discusses how
82    this will change).
83
84    Each object file that is compiled with exception handling contains
85    a static array of exception handlers named __EXCEPTION_TABLE__.
86    Each entry contains the starting and ending addresses of the
87    exception region, and the address of the handler designated for
88    that region.
89
90    At program startup each object file invokes a function named
91    __register_exceptions with the address of its local
92    __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c,
93    and is responsible for recording all of the exception regions into
94    one list (which is kept in a static variable named exception_table_list).
95
96    The function __throw is actually responsible for doing the
97    throw. In the C++ frontend, __throw is generated on a
98    per-object-file basis for each source file compiled with
99    -fexceptions. Before __throw is invoked, the current context
100    of the throw needs to be placed in the global variable __eh_pc.
101
102    __throw attempts to find the appropriate exception handler for the 
103    PC value stored in __eh_pc by calling __find_first_exception_table_match
104    (which is defined in libgcc2.c). If __find_first_exception_table_match
105    finds a relevant handler, __throw jumps directly to it.
106
107    If a handler for the context being thrown from can't be found,
108    __throw is responsible for unwinding the stack, determining the
109    address of the caller of the current function (which will be used
110    as the new context to throw from), and then restarting the process
111    of searching for a handler for the new context. __throw may also
112    call abort if it is unable to unwind the stack, and can also
113    call an external library function named __terminate if it reaches
114    the top of the stack without finding an appropriate handler. (By
115    default __terminate invokes abort, but this behavior can be
116    changed by the user to perform some sort of cleanup behavior before
117    exiting).
118
119    Internal implementation details:
120
121    To associate a user-defined handler with a block of statements, the
122    function expand_start_try_stmts is used to mark the start of the
123    block of statements with which the handler is to be associated
124    (which is known as a "try block"). All statements that appear
125    afterwards will be associated with the try block.
126
127    A call to expand_start_all_catch marks the end of the try block,
128    and also marks the start of the "catch block" (the user-defined
129    handler) associated with the try block.
130
131    This user-defined handler will be invoked for *every* exception
132    thrown with the context of the try block. It is up to the handler
133    to decide whether or not it wishes to handle any given exception,
134    as there is currently no mechanism in this implementation for doing
135    this. (There are plans for conditionally processing an exception
136    based on its "type", which will provide a language-independent
137    mechanism).
138
139    If the handler chooses not to process the exception (perhaps by
140    looking at an "exception type" or some other additional data
141    supplied with the exception), it can fall through to the end of the
142    handler. expand_end_all_catch and expand_leftover_cleanups
143    add additional code to the end of each handler to take care of
144    rethrowing to the outer exception handler.
145
146    The handler also has the option to continue with "normal flow of
147    code", or in other words to resume executing at the statement
148    immediately after the end of the exception region. The variable
149    caught_return_label_stack contains a stack of labels, and jumping
150    to the topmost entry's label via expand_goto will resume normal
151    flow to the statement immediately after the end of the exception
152    region. If the handler falls through to the end, the exception will
153    be rethrown to the outer exception region.
154
155    The instructions for the catch block are kept as a separate
156    sequence, and will be emitted at the end of the function along with
157    the handlers specified via expand_eh_region_end. The end of the
158    catch block is marked with expand_end_all_catch.
159
160    Any data associated with the exception must currently be handled by
161    some external mechanism maintained in the frontend.  For example,
162    the C++ exception mechanism passes an arbitrary value along with
163    the exception, and this is handled in the C++ frontend by using a
164    global variable to hold the value. (This will be changing in the
165    future.)
166
167    The mechanism in C++ for handling data associated with the
168    exception is clearly not thread-safe. For a thread-based
169    environment, another mechanism must be used (possibly using a
170    per-thread allocation mechanism if the size of the area that needs
171    to be allocated isn't known at compile time.)
172
173    Internally-generated exception regions (cleanups) are marked by
174    calling expand_eh_region_start to mark the start of the region,
175    and expand_eh_region_end (handler) is used to both designate the
176    end of the region and to associate a specified handler/cleanup with
177    the region. The rtl code in HANDLER will be invoked whenever an
178    exception occurs in the region between the calls to
179    expand_eh_region_start and expand_eh_region_end. After HANDLER is
180    executed, additional code is emitted to handle rethrowing the
181    exception to the outer exception handler. The code for HANDLER will
182    be emitted at the end of the function.
183
184    TARGET_EXPRs can also be used to designate exception regions. A
185    TARGET_EXPR gives an unwind-protect style interface commonly used
186    in functional languages such as LISP. The associated expression is
187    evaluated, and whether or not it (or any of the functions that it
188    calls) throws an exception, the protect expression is always
189    invoked. This implementation takes care of the details of
190    associating an exception table entry with the expression and
191    generating the necessary code (it actually emits the protect
192    expression twice, once for normal flow and once for the exception
193    case). As for the other handlers, the code for the exception case
194    will be emitted at the end of the function.
195
196    Cleanups can also be specified by using add_partial_entry (handler)
197    and end_protect_partials. add_partial_entry creates the start of
198    a new exception region; HANDLER will be invoked if an exception is
199    thrown with the context of the region between the calls to
200    add_partial_entry and end_protect_partials. end_protect_partials is
201    used to mark the end of these regions. add_partial_entry can be
202    called as many times as needed before calling end_protect_partials.
203    However, end_protect_partials should only be invoked once for each
204    group of calls to add_partial_entry as the entries are queued
205    and all of the outstanding entries are processed simultaneously
206    when end_protect_partials is invoked. Similarly to the other
207    handlers, the code for HANDLER will be emitted at the end of the
208    function.
209
210    The generated RTL for an exception region includes
211    NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
212    the start and end of the exception region. A unique label is also
213    generated at the start of the exception region, which is available
214    by looking at the ehstack variable. The topmost entry corresponds
215    to the current region.
216
217    In the current implementation, an exception can only be thrown from
218    a function call (since the mechanism used to actually throw an
219    exception involves calling __throw).  If an exception region is
220    created but no function calls occur within that region, the region
221    can be safely optimized away (along with its exception handlers)
222    since no exceptions can ever be caught in that region.  This
223    optimization is performed unless -fasynchronous-exceptions is
224    given.  If the user wishes to throw from a signal handler, or other
225    asynchronous place, -fasynchronous-exceptions should be used when
226    compiling for maximally correct code, at the cost of additional
227    exception regions.  Using -fasynchronous-exceptions only produces
228    code that is reasonably safe in such situations, but a correct
229    program cannot rely upon this working.  It can be used in failsafe
230    code, where trying to continue on, and proceeding with potentially
231    incorrect results is better than halting the program.
232
233
234    Unwinding the stack:
235
236    The details of unwinding the stack to the next frame can be rather
237    complex. While in many cases a generic __unwind_function routine
238    can be used by the generated exception handling code to do this, it
239    is often necessary to generate inline code to do the unwinding.
240
241    Whether or not these inlined unwinders are necessary is
242    target-specific.
243
244    By default, if the target-specific backend doesn't supply a
245    definition for __unwind_function, inlined unwinders will be used
246    instead. The main tradeoff here is in text space utilization.
247    Obviously, if inline unwinders have to be generated repeatedly,
248    this uses much more space than if a single routine is used.
249
250    However, it is simply not possible on some platforms to write a
251    generalized routine for doing stack unwinding without having some
252    form of additional data associated with each function. The current
253    implementation encodes this data in the form of additional machine
254    instructions. This is clearly not desirable, as it is extremely
255    inefficient. The next implementation will provide a set of metadata
256    for each function that will provide the needed information.
257
258    The backend macro DOESNT_NEED_UNWINDER is used to conditionalize
259    whether or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER
260    is defined and has a non-zero value, a per-function unwinder is
261    not emitted for the current function.
262
263    On some platforms it is possible that neither __unwind_function
264    nor inlined unwinders are available. For these platforms it is not
265    possible to throw through a function call, and abort will be
266    invoked instead of performing the throw. 
267
268    Future directions:
269
270    Currently __throw makes no differentiation between cleanups and
271    user-defined exception regions. While this makes the implementation
272    simple, it also implies that it is impossible to determine if a
273    user-defined exception handler exists for a given exception without
274    completely unwinding the stack in the process. This is undesirable
275    from the standpoint of debugging, as ideally it would be possible
276    to trap unhandled exceptions in the debugger before the process of
277    unwinding has even started.
278
279    This problem can be solved by marking user-defined handlers in a
280    special way (probably by adding additional bits to exception_table_list).
281    A two-pass scheme could then be used by __throw to iterate
282    through the table. The first pass would search for a relevant
283    user-defined handler for the current context of the throw, and if
284    one is found, the second pass would then invoke all needed cleanups
285    before jumping to the user-defined handler.
286
287    Many languages (including C++ and Ada) make execution of a
288    user-defined handler conditional on the "type" of the exception
289    thrown. (The type of the exception is actually the type of the data
290    that is thrown with the exception.) It will thus be necessary for
291    __throw to be able to determine if a given user-defined
292    exception handler will actually be executed, given the type of
293    exception.
294
295    One scheme is to add additional information to exception_table_list
296    as to the types of exceptions accepted by each handler. __throw
297    can do the type comparisons and then determine if the handler is
298    actually going to be executed.
299
300    There is currently no significant level of debugging support
301    available, other than to place a breakpoint on __throw. While
302    this is sufficient in most cases, it would be helpful to be able to
303    know where a given exception was going to be thrown to before it is
304    actually thrown, and to be able to choose between stopping before
305    every exception region (including cleanups), or just user-defined
306    exception regions. This should be possible to do in the two-pass
307    scheme by adding additional labels to __throw for appropriate
308    breakpoints, and additional debugger commands could be added to
309    query various state variables to determine what actions are to be
310    performed next.
311
312    Another major problem that is being worked on is the issue with
313    stack unwinding on various platforms. Currently the only platform
314    that has support for __unwind_function is the Sparc; all other
315    ports require per-function unwinders, which causes large amounts of
316    code bloat.
317
318    Ideally it would be possible to store a small set of metadata with
319    each function that would then make it possible to write a
320    __unwind_function for every platform. This would eliminate the
321    need for per-function unwinders.
322
323    The main reason the data is needed is that on some platforms the
324    order and types of data stored on the stack can vary depending on
325    the type of function, its arguments and returned values, and the
326    compilation options used (optimization versus non-optimization,
327    -fomit-frame-pointer, processor variations, etc).
328
329    Unfortunately, this also means that throwing through functions that
330    aren't compiled with exception handling support will still not be
331    possible on some platforms. This problem is currently being
332    investigated, but no solutions have been found that do not imply
333    some unacceptable performance penalties.
334
335    For setjmp/longjmp based exception handling, some of the details
336    are as above, but there are some additional details.  This section
337    discusses the details.
338
339    We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs.  We don't
340    optimize EH regions yet.  We don't have to worry about machine
341    specific issues with unwinding the stack, as we rely upon longjmp
342    for all the machine specific details.  There is no variable context
343    of a throw, just the one implied by the dynamic handler stack
344    pointed to by the dynamic handler chain.  There is no exception
345    table, and no calls to __register_excetpions.  __sjthrow is used
346    instead of __throw, and it works by using the dynamic handler
347    chain, and longjmp.  -fasynchronous-exceptions has no effect, as
348    the elimination of trivial exception regions is not yet performed.
349
350    A frontend can set protect_cleanup_actions_with_terminate when all
351    the cleanup actions should be protected with an EH region that
352    calls terminate when an unhandled exception is throw.  C++ does
353    this, Ada does not.  */
354
355
356 #include "config.h"
357 #include <stdio.h>
358 #include "rtl.h"
359 #include "tree.h"
360 #include "flags.h"
361 #include "except.h"
362 #include "function.h"
363 #include "insn-flags.h"
364 #include "expr.h"
365 #include "insn-codes.h"
366 #include "regs.h"
367 #include "hard-reg-set.h"
368 #include "insn-config.h"
369 #include "recog.h"
370 #include "output.h"
371 #include "assert.h"
372
373 /* One to use setjmp/longjmp method of generating code for exception
374    handling.  */
375
376 int exceptions_via_longjmp = 1;
377
378 /* One to enable asynchronous exception support.  */
379
380 int asynchronous_exceptions = 0;
381
382 /* One to protect cleanup actions with a handler that calls
383    __terminate, zero otherwise.  */
384
385 int protect_cleanup_actions_with_terminate = 0;
386
387 /* A list of labels used for exception handlers.  Created by
388    find_exception_handler_labels for the optimization passes.  */
389
390 rtx exception_handler_labels;
391
392 /* Nonzero means that __throw was invoked. 
393
394    This is used by the C++ frontend to know if code needs to be emitted
395    for __throw or not.  */
396
397 int throw_used;
398
399 /* The dynamic handler chain.  Nonzero if the function has already
400    fetched a pointer to the dynamic handler chain for exception
401    handling.  */
402
403 rtx current_function_dhc;
404
405 /* The dynamic cleanup chain.  Nonzero if the function has already
406    fetched a pointer to the dynamic cleanup chain for exception
407    handling.  */
408
409 rtx current_function_dcc;
410
411 /* A stack used for keeping track of the currectly active exception
412    handling region.  As each exception region is started, an entry
413    describing the region is pushed onto this stack.  The current
414    region can be found by looking at the top of the stack, and as we
415    exit regions, the corresponding entries are popped. 
416
417    Entries cannot overlap; they can be nested. So there is only one
418    entry at most that corresponds to the current instruction, and that
419    is the entry on the top of the stack.  */
420
421 static struct eh_stack ehstack;
422
423 /* A queue used for tracking which exception regions have closed but
424    whose handlers have not yet been expanded. Regions are emitted in
425    groups in an attempt to improve paging performance.
426
427    As we exit a region, we enqueue a new entry. The entries are then
428    dequeued during expand_leftover_cleanups and expand_start_all_catch,
429
430    We should redo things so that we either take RTL for the handler,
431    or we expand the handler expressed as a tree immediately at region
432    end time.  */
433
434 static struct eh_queue ehqueue;
435
436 /* Insns for all of the exception handlers for the current function.
437    They are currently emitted by the frontend code.  */
438
439 rtx catch_clauses;
440
441 /* A TREE_CHAINed list of handlers for regions that are not yet
442    closed. The TREE_VALUE of each entry contains the handler for the
443    corresponding entry on the ehstack.  */
444
445 static tree protect_list;
446
447 /* Stacks to keep track of various labels.  */
448
449 /* Keeps track of the label to resume to should one want to resume
450    normal control flow out of a handler (instead of, say, returning to
451    the caller of the current function or exiting the program).  Also
452    used as the context of a throw to rethrow an exception to the outer
453    exception region.  */
454
455 struct label_node *caught_return_label_stack = NULL;
456
457 /* A random data area for the front end's own use.  */
458
459 struct label_node *false_label_stack = NULL;
460
461 /* The rtx and the tree for the saved PC value.  */
462
463 rtx eh_saved_pc_rtx;
464 tree eh_saved_pc;
465
466 rtx expand_builtin_return_addr  PROTO((enum built_in_function, int, rtx));
467 \f
468 /* Various support routines to manipulate the various data structures
469    used by the exception handling code.  */
470
471 /* Push a label entry onto the given STACK.  */
472
473 void
474 push_label_entry (stack, rlabel, tlabel)
475      struct label_node **stack;
476      rtx rlabel;
477      tree tlabel;
478 {
479   struct label_node *newnode
480     = (struct label_node *) xmalloc (sizeof (struct label_node));
481
482   if (rlabel)
483     newnode->u.rlabel = rlabel;
484   else
485     newnode->u.tlabel = tlabel;
486   newnode->chain = *stack;
487   *stack = newnode;
488 }
489
490 /* Pop a label entry from the given STACK.  */
491
492 rtx
493 pop_label_entry (stack)
494      struct label_node **stack;
495 {
496   rtx label;
497   struct label_node *tempnode;
498
499   if (! *stack)
500     return NULL_RTX;
501
502   tempnode = *stack;
503   label = tempnode->u.rlabel;
504   *stack = (*stack)->chain;
505   free (tempnode);
506
507   return label;
508 }
509
510 /* Return the top element of the given STACK.  */
511
512 tree
513 top_label_entry (stack)
514      struct label_node **stack;
515 {
516   if (! *stack)
517     return NULL_TREE;
518
519   return (*stack)->u.tlabel;
520 }
521
522 /* Make a copy of ENTRY using xmalloc to allocate the space.  */
523
524 static struct eh_entry *
525 copy_eh_entry (entry)
526      struct eh_entry *entry;
527 {
528   struct eh_entry *newentry;
529
530   newentry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
531   bcopy ((char *) entry, (char *) newentry, sizeof (struct eh_entry));
532
533   return newentry;
534 }
535
536 /* Push a new eh_node entry onto STACK.  */
537
538 static void
539 push_eh_entry (stack)
540      struct eh_stack *stack;
541 {
542   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
543   struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
544
545   entry->outer_context = gen_label_rtx ();
546   entry->exception_handler_label = gen_label_rtx ();
547   entry->finalization = NULL_TREE;
548
549   node->entry = entry;
550   node->chain = stack->top;
551   stack->top = node;
552 }
553
554 /* Pop an entry from the given STACK.  */
555
556 static struct eh_entry *
557 pop_eh_entry (stack)
558      struct eh_stack *stack;
559 {
560   struct eh_node *tempnode;
561   struct eh_entry *tempentry;
562   
563   tempnode = stack->top;
564   tempentry = tempnode->entry;
565   stack->top = stack->top->chain;
566   free (tempnode);
567
568   return tempentry;
569 }
570
571 /* Enqueue an ENTRY onto the given QUEUE.  */
572
573 static void
574 enqueue_eh_entry (queue, entry)
575      struct eh_queue *queue;
576      struct eh_entry *entry;
577 {
578   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
579
580   node->entry = entry;
581   node->chain = NULL;
582
583   if (queue->head == NULL)
584     {
585       queue->head = node;
586     }
587   else
588     {
589       queue->tail->chain = node;
590     }
591   queue->tail = node;
592 }
593
594 /* Dequeue an entry from the given QUEUE.  */
595
596 static struct eh_entry *
597 dequeue_eh_entry (queue)
598      struct eh_queue *queue;
599 {
600   struct eh_node *tempnode;
601   struct eh_entry *tempentry;
602
603   if (queue->head == NULL)
604     return NULL;
605
606   tempnode = queue->head;
607   queue->head = queue->head->chain;
608
609   tempentry = tempnode->entry;
610   free (tempnode);
611
612   return tempentry;
613 }
614 \f
615 /* Routine to see if exception exception handling is turned on.
616    DO_WARN is non-zero if we want to inform the user that exception
617    handling is turned off. 
618
619    This is used to ensure that -fexceptions has been specified if the
620    compiler tries to use any exception-specific functions.  */
621
622 int
623 doing_eh (do_warn)
624      int do_warn;
625 {
626   if (! flag_exceptions)
627     {
628       static int warned = 0;
629       if (! warned && do_warn)
630         {
631           error ("exception handling disabled, use -fexceptions to enable");
632           warned = 1;
633         }
634       return 0;
635     }
636   return 1;
637 }
638
639 /* Given a return address in ADDR, determine the address we should use
640    to find the corresponding EH region.  */
641
642 rtx
643 eh_outer_context (addr)
644      rtx addr;
645 {
646   /* First mask out any unwanted bits.  */
647 #ifdef MASK_RETURN_ADDR
648   emit_insn (gen_rtx (SET, Pmode,
649                       addr,
650                       gen_rtx (AND, Pmode,
651                                addr, MASK_RETURN_ADDR)));
652 #endif
653
654   /* Then subtract out enough to get into the appropriate region.  If
655      this is defined, assume we don't need to subtract anything as it
656      is already within the correct region.  */
657 #if ! defined (RETURN_ADDR_OFFSET)
658   addr = plus_constant (addr, -1);
659 #endif
660
661   return addr;
662 }
663
664 /* Start a new exception region for a region of code that has a
665    cleanup action and push the HANDLER for the region onto
666    protect_list. All of the regions created with add_partial_entry
667    will be ended when end_protect_partials is invoked.  */
668
669 void
670 add_partial_entry (handler)
671      tree handler;
672 {
673   expand_eh_region_start ();
674
675   /* Make sure the entry is on the correct obstack.  */
676   push_obstacks_nochange ();
677   resume_temporary_allocation ();
678
679   /* Because this is a cleanup action, we may have to protect the handler
680      with __terminate.  */
681   handler = protect_with_terminate (handler);
682
683   protect_list = tree_cons (NULL_TREE, handler, protect_list);
684   pop_obstacks ();
685 }
686
687 /* Get a reference to the dynamic handler chain.  It points to the
688    pointer to the next element in the dynamic handler chain.  It ends
689    when there are no more elements in the dynamic handler chain, when
690    the value is &top_elt from libgcc2.c.  Immediately after the
691    pointer, is an area suitable for setjmp/longjmp when
692    DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for
693    __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP
694    isn't defined.
695
696    This routine is here to facilitate the porting of this code to
697    systems with threads.  One can either replace the routine we emit a
698    call for here in libgcc2.c, or one can modify this routine to work
699    with their thread system.  */
700
701 rtx
702 get_dynamic_handler_chain ()
703 {
704 #if 0
705   /* Do this once we figure out how to get this to the front of the
706      function, and we really only want one per real function, not one
707      per inlined function.  */
708   if (current_function_dhc == 0)
709     {
710       rtx dhc, insns;
711       start_sequence ();
712
713       dhc = emit_library_call_value (get_dynamic_handler_chain_libfunc,
714                                      NULL_RTX, 1,
715                                      Pmode, 0);
716       current_function_dhc = copy_to_reg (dhc);
717       insns = get_insns ();
718       end_sequence ();
719       emit_insns_before (insns, get_first_nonparm_insn ());
720     }
721 #else
722   rtx dhc;
723   dhc = emit_library_call_value (get_dynamic_handler_chain_libfunc,
724                                  NULL_RTX, 1,
725                                  Pmode, 0);
726   current_function_dhc = copy_to_reg (dhc);
727 #endif
728
729   /* We don't want a copy of the dhc, but rather, the single dhc.  */
730   return gen_rtx (MEM, Pmode, current_function_dhc);
731 }
732
733 /* Get a reference to the dynamic cleanup chain.  It points to the
734    pointer to the next element in the dynamic cleanup chain.
735    Immediately after the pointer, are two Pmode variables, one for a
736    pointer to a function that performs the cleanup action, and the
737    second, the argument to pass to that function.  */
738
739 rtx
740 get_dynamic_cleanup_chain ()
741 {
742   rtx dhc, dcc;
743
744   dhc = get_dynamic_handler_chain ();
745   dcc = plus_constant (dhc, GET_MODE_SIZE (Pmode));
746
747   current_function_dcc = copy_to_reg (dcc);
748
749   /* We don't want a copy of the dcc, but rather, the single dcc.  */
750   return gen_rtx (MEM, Pmode, current_function_dcc);
751 }
752
753 /* Generate code to evaluate X and jump to LABEL if the value is nonzero.
754    LABEL is an rtx of code CODE_LABEL, in this function.  */
755
756 void
757 jumpif_rtx (x, label)
758      rtx x;
759      rtx label;
760 {
761   jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
762 }
763
764 /* Generate code to evaluate X and jump to LABEL if the value is zero.
765    LABEL is an rtx of code CODE_LABEL, in this function.  */
766
767 void
768 jumpifnot_rtx (x, label)
769      rtx x;
770      rtx label;
771 {
772   jumpifnot (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
773 }
774
775 /* Start a dynamic cleanup on the EH runtime dynamic cleanup stack.
776    We just need to create an element for the cleanup list, and push it
777    into the chain.
778
779    A dynamic cleanup is a cleanup action implied by the presence of an
780    element on the EH runtime dynamic cleanup stack that is to be
781    performed when an exception is thrown.  The cleanup action is
782    performed by __sjthrow when an exception is thrown.  Only certain
783    actions can be optimized into dynamic cleanup actions.  For the
784    restrictions on what actions can be performed using this routine,
785    see expand_eh_region_start_tree.  */
786
787 static void
788 start_dynamic_cleanup (func, arg)
789      tree func;
790      tree arg;
791 {
792   rtx dhc, dcc;
793   rtx new_func, new_arg;
794   rtx x, buf;
795   int size;
796
797   /* We allocate enough room for a pointer to the function, and
798      one argument.  */
799   size = 2;
800
801   /* XXX, FIXME: The stack space allocated this way is too long lived,
802      but there is no allocation routine that allocates at the level of
803      the last binding contour.  */
804   buf = assign_stack_local (BLKmode,
805                             GET_MODE_SIZE (Pmode)*(size+1),
806                             0);
807
808   buf = change_address (buf, Pmode, NULL_RTX);
809
810   /* Store dcc into the first word of the newly allocated buffer.  */
811
812   dcc = get_dynamic_cleanup_chain ();
813   emit_move_insn (buf, dcc);
814
815   /* Store func and arg into the cleanup list element.  */
816
817   new_func = gen_rtx (MEM, Pmode, plus_constant (XEXP (buf, 0),
818                                                  GET_MODE_SIZE (Pmode)));
819   new_arg = gen_rtx (MEM, Pmode, plus_constant (XEXP (buf, 0),
820                                                 GET_MODE_SIZE (Pmode)*2));
821   x = expand_expr (func, new_func, Pmode, 0);
822   if (x != new_func)
823     emit_move_insn (new_func, x);
824
825   x = expand_expr (arg, new_arg, Pmode, 0);
826   if (x != new_arg)
827     emit_move_insn (new_arg, x);
828
829   /* Update the cleanup chain.  */
830
831   emit_move_insn (dcc, XEXP (buf, 0));
832 }
833
834 /* Emit RTL to start a dynamic handler on the EH runtime dynamic
835    handler stack.  This should only be used by expand_eh_region_start
836    or expand_eh_region_start_tree.  */
837
838 static void
839 start_dynamic_handler ()
840 {
841   rtx dhc, dcc;
842   rtx x, arg, buf;
843   int size;
844
845 #ifndef DONT_USE_BUILTIN_SETJMP
846   /* The number of Pmode words for the setjmp buffer, when using the
847      builtin setjmp/longjmp, see expand_builtin, case
848      BUILT_IN_LONGJMP.  */
849   size = 5;
850 #else
851 #ifdef JMP_BUF_SIZE
852   size = JMP_BUF_SIZE;
853 #else
854   /* Should be large enough for most systems, if it is not,
855      JMP_BUF_SIZE should be defined with the proper value.  It will
856      also tend to be larger than necessary for most systems, a more
857      optimal port will define JMP_BUF_SIZE.  */
858   size = FIRST_PSEUDO_REGISTER+2;
859 #endif
860 #endif
861   /* XXX, FIXME: The stack space allocated this way is too long lived,
862      but there is no allocation routine that allocates at the level of
863      the last binding contour.  */
864   arg = assign_stack_local (BLKmode,
865                             GET_MODE_SIZE (Pmode)*(size+1),
866                             0);
867
868   arg = change_address (arg, Pmode, NULL_RTX);
869
870   /* Store dhc into the first word of the newly allocated buffer.  */
871
872   dhc = get_dynamic_handler_chain ();
873   dcc = gen_rtx (MEM, Pmode, plus_constant (XEXP (arg, 0),
874                                             GET_MODE_SIZE (Pmode)));
875   emit_move_insn (arg, dhc);
876
877   /* Zero out the start of the cleanup chain.  */
878   emit_move_insn (dcc, const0_rtx);
879
880   /* The jmpbuf starts two words into the area allocated.  */
881   buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
882
883 #ifdef DONT_USE_BUILTIN_SETJMP
884   x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
885                                buf, Pmode);
886 #else
887   x = expand_builtin_setjmp (buf, NULL_RTX);
888 #endif
889
890   /* If we come back here for a catch, transfer control to the
891      handler.  */
892
893   jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
894
895   /* We are committed to this, so update the handler chain.  */
896
897   emit_move_insn (dhc, XEXP (arg, 0));
898 }
899
900 /* Start an exception handling region for the given cleanup action.
901    All instructions emitted after this point are considered to be part
902    of the region until expand_eh_region_end is invoked.  CLEANUP is
903    the cleanup action to perform.  The return value is true if the
904    exception region was optimized away.  If that case,
905    expand_eh_region_end does not need to be called for this cleanup,
906    nor should it be.
907
908    This routine notices one particular common case in C++ code
909    generation, and optimizes it so as to not need the exception
910    region.  It works by creating a dynamic cleanup action, instead of
911    of a using an exception region.  */
912
913 int
914 expand_eh_region_start_tree (decl, cleanup)
915      tree decl;
916      tree cleanup;
917 {
918   rtx note;
919
920   /* This is the old code.  */
921   if (! doing_eh (0))
922     return 0;
923
924   /* The optimization only applies to actions protected with
925      terminate, and only applies if we are using the setjmp/longjmp
926      codegen method.  */
927   if (exceptions_via_longjmp
928       && protect_cleanup_actions_with_terminate)
929     {
930       tree func, arg;
931       tree args;
932
933       /* Ignore any UNSAVE_EXPR.  */
934       if (TREE_CODE (cleanup) == UNSAVE_EXPR)
935         cleanup = TREE_OPERAND (cleanup, 0);
936       
937       /* Further, it only applies if the action is a call, if there
938          are 2 arguments, and if the second argument is 2.  */
939
940       if (TREE_CODE (cleanup) == CALL_EXPR
941           && (args = TREE_OPERAND (cleanup, 1))
942           && (func = TREE_OPERAND (cleanup, 0))
943           && (arg = TREE_VALUE (args))
944           && (args = TREE_CHAIN (args))
945
946           /* is the second argument 2?  */
947           && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST
948           && TREE_INT_CST_LOW (TREE_VALUE (args)) == 2
949           && TREE_INT_CST_HIGH (TREE_VALUE (args)) == 0
950
951           /* Make sure there are no other arguments.  */
952           && TREE_CHAIN (args) == NULL_TREE)
953         {
954           /* Arrange for returns and gotos to pop the entry we make on the
955              dynamic cleanup stack.  */
956           expand_dcc_cleanup (decl);
957           start_dynamic_cleanup (func, arg);
958           return 1;
959         }
960     }
961
962   expand_eh_region_start_for_decl (decl);
963
964   return 0;
965 }
966
967 /* Just like expand_eh_region_start, except if a cleanup action is
968    entered on the cleanup chain, the TREE_PURPOSE of the element put
969    on the chain is DECL.  DECL should be the associated VAR_DECL, if
970    any, otherwise it should be NULL_TREE.  */
971
972 void
973 expand_eh_region_start_for_decl (decl)
974      tree decl;
975 {
976   rtx note;
977
978   /* This is the old code.  */
979   if (! doing_eh (0))
980     return;
981
982   if (exceptions_via_longjmp)
983     {
984       /* We need a new block to record the start and end of the
985          dynamic handler chain.  We could always do this, but we
986          really want to permit jumping into such a block, and we want
987          to avoid any errors or performance impact in the SJ EH code
988          for now.  */
989       expand_start_bindings (0);
990
991       /* But we don't need or want a new temporary level.  */
992       pop_temp_slots ();
993
994       /* Mark this block as created by expand_eh_region_start.  This
995          is so that we can pop the block with expand_end_bindings
996          automatically.  */
997       mark_block_as_eh_region ();
998
999       /* Arrange for returns and gotos to pop the entry we make on the
1000          dynamic handler stack.  */
1001       expand_dhc_cleanup (decl);
1002     }
1003
1004   if (exceptions_via_longjmp == 0)
1005     note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
1006   push_eh_entry (&ehstack);
1007   if (exceptions_via_longjmp == 0)
1008     NOTE_BLOCK_NUMBER (note)
1009       = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
1010   if (exceptions_via_longjmp)
1011     start_dynamic_handler ();
1012 }
1013
1014 /* Start an exception handling region.  All instructions emitted after
1015    this point are considered to be part of the region until
1016    expand_eh_region_end is invoked.  */
1017
1018 void
1019 expand_eh_region_start ()
1020 {
1021   expand_eh_region_start_for_decl (NULL_TREE);
1022 }
1023
1024 /* End an exception handling region.  The information about the region
1025    is found on the top of ehstack.
1026
1027    HANDLER is either the cleanup for the exception region, or if we're
1028    marking the end of a try block, HANDLER is integer_zero_node.
1029
1030    HANDLER will be transformed to rtl when expand_leftover_cleanups
1031    is invoked.  */
1032
1033 void
1034 expand_eh_region_end (handler)
1035      tree handler;
1036 {
1037   struct eh_entry *entry;
1038
1039   if (! doing_eh (0))
1040     return;
1041
1042   entry = pop_eh_entry (&ehstack);
1043
1044   if (exceptions_via_longjmp == 0)
1045     {
1046       rtx label;
1047       rtx note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
1048       NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
1049
1050       label = gen_label_rtx ();
1051       emit_jump (label);
1052
1053       /* Emit a label marking the end of this exception region that
1054          is used for rethrowing into the outer context.  */
1055       emit_label (entry->outer_context);
1056
1057       /* Put in something that takes up space, as otherwise the end
1058          address for this EH region could have the exact same address as
1059          its outer region. This would cause us to miss the fact that
1060          resuming exception handling with this PC value would be inside
1061          the outer region.  */
1062       emit_insn (gen_nop ());
1063       emit_barrier ();
1064       emit_label (label);
1065     }
1066
1067   entry->finalization = handler;
1068
1069   enqueue_eh_entry (&ehqueue, entry);
1070
1071   /* If we have already started ending the bindings, don't recurse.
1072      This only happens when exceptions_via_longjmp is true.  */
1073   if (is_eh_region ())
1074     {
1075       /* Because we don't need or want a new temporary level and
1076          because we didn't create one in expand_eh_region_start,
1077          create a fake one now to avoid removing one in
1078          expand_end_bindings.  */
1079       push_temp_slots ();
1080
1081       mark_block_as_not_eh_region ();
1082
1083       /* Maybe do this to prevent jumping in and so on...  */
1084       expand_end_bindings (NULL_TREE, 0, 0);
1085     }
1086 }
1087
1088 /* If we are using the setjmp/longjmp EH codegen method, we emit a
1089    call to __sjthrow.
1090
1091    Otherwise, we emit a call to __throw and note that we threw
1092    something, so we know we need to generate the necessary code for
1093    __throw.
1094
1095    Before invoking throw, the __eh_pc variable must have been set up
1096    to contain the PC being thrown from. This address is used by
1097    __throw to determine which exception region (if any) is
1098    responsible for handling the exception.  */
1099
1100 void
1101 emit_throw ()
1102 {
1103   if (exceptions_via_longjmp)
1104     {
1105       emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0);
1106     }
1107   else
1108     {
1109 #ifdef JUMP_TO_THROW
1110       emit_indirect_jump (throw_libfunc);
1111 #else
1112       SYMBOL_REF_USED (throw_libfunc) = 1;
1113       emit_library_call (throw_libfunc, 0, VOIDmode, 0);
1114 #endif
1115       throw_used = 1;
1116     }
1117   emit_barrier ();
1118 }
1119
1120 /* An internal throw with an indirect CONTEXT we want to throw from.
1121    CONTEXT evaluates to the context of the throw.  */
1122
1123 static void
1124 expand_internal_throw_indirect (context)
1125      rtx context;
1126 {
1127   assemble_external (eh_saved_pc);
1128   emit_move_insn (eh_saved_pc_rtx, context);
1129   emit_throw ();
1130 }
1131
1132 /* An internal throw with a direct CONTEXT we want to throw from.
1133    CONTEXT must be a label; its address will be used as the context of
1134    the throw.  */
1135
1136 void
1137 expand_internal_throw (context)
1138      rtx context;
1139 {
1140   expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
1141 }
1142
1143 /* Called from expand_exception_blocks and expand_end_catch_block to
1144    emit any pending handlers/cleanups queued from expand_eh_region_end.  */
1145
1146 void
1147 expand_leftover_cleanups ()
1148 {
1149   struct eh_entry *entry;
1150
1151   while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
1152     {
1153       rtx prev;
1154
1155       /* A leftover try block. Shouldn't be one here.  */
1156       if (entry->finalization == integer_zero_node)
1157         abort ();
1158
1159       /* Output the label for the start of the exception handler.  */
1160       emit_label (entry->exception_handler_label);
1161
1162 #ifdef HAVE_exception_receiver
1163       if (! exceptions_via_longjmp)
1164         if (HAVE_exception_receiver)
1165           emit_insn (gen_exception_receiver ());
1166 #endif
1167
1168 #ifdef HAVE_nonlocal_goto_receiver
1169       if (! exceptions_via_longjmp)
1170         if (HAVE_nonlocal_goto_receiver)
1171           emit_insn (gen_nonlocal_goto_receiver ());
1172 #endif
1173
1174       /* And now generate the insns for the handler.  */
1175       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1176
1177       prev = get_last_insn ();
1178       if (prev == NULL || GET_CODE (prev) != BARRIER)
1179         {
1180           if (exceptions_via_longjmp)
1181             emit_throw ();
1182           else
1183             {
1184               /* The below can be optimized away, and we could just
1185                  fall into the next EH handler, if we are certain they
1186                  are nested.  */
1187               /* Emit code to throw to the outer context if we fall off
1188                  the end of the handler.  */
1189               expand_internal_throw (entry->outer_context);
1190             }
1191         }
1192
1193       free (entry);
1194     }
1195 }
1196
1197 /* Called at the start of a block of try statements.  */
1198 void
1199 expand_start_try_stmts ()
1200 {
1201   if (! doing_eh (1))
1202     return;
1203
1204   expand_eh_region_start ();
1205 }
1206
1207 /* Generate RTL for the start of a group of catch clauses. 
1208
1209    It is responsible for starting a new instruction sequence for the
1210    instructions in the catch block, and expanding the handlers for the
1211    internally-generated exception regions nested within the try block
1212    corresponding to this catch block.  */
1213
1214 void
1215 expand_start_all_catch ()
1216 {
1217   struct eh_entry *entry;
1218   tree label;
1219
1220   if (! doing_eh (1))
1221     return;
1222
1223   /* End the try block.  */
1224   expand_eh_region_end (integer_zero_node);
1225
1226   emit_line_note (input_filename, lineno);
1227   label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1228
1229   /* The label for the exception handling block that we will save.
1230      This is Lresume in the documention.  */
1231   expand_label (label);
1232   
1233   if (exceptions_via_longjmp == 0)
1234     {
1235       /* Put in something that takes up space, as otherwise the end
1236          address for the EH region could have the exact same address as
1237          the outer region, causing us to miss the fact that resuming
1238          exception handling with this PC value would be inside the outer
1239          region.  */
1240       emit_insn (gen_nop ());
1241     }
1242
1243   /* Push the label that points to where normal flow is resumed onto
1244      the top of the label stack.  */
1245   push_label_entry (&caught_return_label_stack, NULL_RTX, label);
1246
1247   /* Start a new sequence for all the catch blocks.  We will add this
1248      to the global sequence catch_clauses when we have completed all
1249      the handlers in this handler-seq.  */
1250   start_sequence ();
1251
1252   while (1)
1253     {
1254       rtx prev;
1255
1256       entry = dequeue_eh_entry (&ehqueue);
1257       /* Emit the label for the exception handler for this region, and
1258          expand the code for the handler. 
1259
1260          Note that a catch region is handled as a side-effect here;
1261          for a try block, entry->finalization will contain
1262          integer_zero_node, so no code will be generated in the
1263          expand_expr call below. But, the label for the handler will
1264          still be emitted, so any code emitted after this point will
1265          end up being the handler.  */
1266       emit_label (entry->exception_handler_label);
1267
1268 #ifdef HAVE_exception_receiver
1269       if (! exceptions_via_longjmp)
1270         if (HAVE_exception_receiver)
1271           emit_insn (gen_exception_receiver ());
1272 #endif
1273
1274 #ifdef HAVE_nonlocal_goto_receiver
1275       if (! exceptions_via_longjmp)
1276         if (HAVE_nonlocal_goto_receiver)
1277           emit_insn (gen_nonlocal_goto_receiver ());
1278 #endif
1279
1280       /* When we get down to the matching entry for this try block, stop.  */
1281       if (entry->finalization == integer_zero_node)
1282         {
1283           /* Don't forget to free this entry.  */
1284           free (entry);
1285           break;
1286         }
1287
1288       /* And now generate the insns for the handler.  */
1289       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1290
1291       prev = get_last_insn ();
1292       if (prev == NULL || GET_CODE (prev) != BARRIER)
1293         {
1294           if (exceptions_via_longjmp)
1295             emit_throw ();
1296           else
1297             {
1298               /* Code to throw out to outer context when we fall off end
1299                  of the handler. We can't do this here for catch blocks,
1300                  so it's done in expand_end_all_catch instead.
1301
1302                  The below can be optimized away (and we could just fall
1303                  into the next EH handler) if we are certain they are
1304                  nested.  */
1305
1306               expand_internal_throw (entry->outer_context);
1307             }
1308         }
1309       free (entry);
1310     }
1311 }
1312
1313 /* Finish up the catch block.  At this point all the insns for the
1314    catch clauses have already been generated, so we only have to add
1315    them to the catch_clauses list. We also want to make sure that if
1316    we fall off the end of the catch clauses that we rethrow to the
1317    outer EH region.  */
1318
1319 void
1320 expand_end_all_catch ()
1321 {
1322   rtx new_catch_clause;
1323
1324   if (! doing_eh (1))
1325     return;
1326
1327   if (exceptions_via_longjmp)
1328     emit_throw ();
1329   else
1330     {
1331       /* Code to throw out to outer context, if we fall off end of catch
1332          handlers.  This is rethrow (Lresume, same id, same obj) in the
1333          documentation. We use Lresume because we know that it will throw
1334          to the correct context.
1335
1336          In other words, if the catch handler doesn't exit or return, we
1337          do a "throw" (using the address of Lresume as the point being
1338          thrown from) so that the outer EH region can then try to process
1339          the exception.  */
1340
1341       expand_internal_throw (DECL_RTL (top_label_entry (&caught_return_label_stack)));
1342     }
1343
1344   /* Now we have the complete catch sequence.  */
1345   new_catch_clause = get_insns ();
1346   end_sequence ();
1347   
1348   /* This level of catch blocks is done, so set up the successful
1349      catch jump label for the next layer of catch blocks.  */
1350   pop_label_entry (&caught_return_label_stack);
1351
1352   /* Add the new sequence of catches to the main one for this function.  */
1353   push_to_sequence (catch_clauses);
1354   emit_insns (new_catch_clause);
1355   catch_clauses = get_insns ();
1356   end_sequence ();
1357   
1358   /* Here we fall through into the continuation code.  */
1359 }
1360
1361 /* End all the pending exception regions on protect_list. The handlers
1362    will be emitted when expand_leftover_cleanups is invoked.  */
1363
1364 void
1365 end_protect_partials ()
1366 {
1367   while (protect_list)
1368     {
1369       expand_eh_region_end (TREE_VALUE (protect_list));
1370       protect_list = TREE_CHAIN (protect_list);
1371     }
1372 }
1373
1374 /* Arrange for __terminate to be called if there is an unhandled throw
1375    from within E.  */
1376
1377 tree
1378 protect_with_terminate (e)
1379      tree e;
1380 {
1381   /* We only need to do this when using setjmp/longjmp EH and the
1382      language requires it, as otherwise we protect all of the handlers
1383      at once, if we need to.  */
1384   if (exceptions_via_longjmp && protect_cleanup_actions_with_terminate)
1385     {
1386       tree handler, result;
1387
1388       /* All cleanups must be on the function_obstack.  */
1389       push_obstacks_nochange ();
1390       resume_temporary_allocation ();
1391
1392       handler = make_node (RTL_EXPR);
1393       TREE_TYPE (handler) = void_type_node;
1394       RTL_EXPR_RTL (handler) = const0_rtx;
1395       TREE_SIDE_EFFECTS (handler) = 1;
1396       start_sequence_for_rtl_expr (handler);
1397
1398       emit_library_call (terminate_libfunc, 0, VOIDmode, 0);
1399       emit_barrier ();
1400
1401       RTL_EXPR_SEQUENCE (handler) = get_insns ();
1402       end_sequence ();
1403         
1404       result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler);
1405       TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
1406       TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
1407       TREE_READONLY (result) = TREE_READONLY (e);
1408
1409       pop_obstacks ();
1410
1411       e = result;
1412     }
1413
1414   return e;
1415 }
1416 \f
1417 /* The exception table that we build that is used for looking up and
1418    dispatching exceptions, the current number of entries, and its
1419    maximum size before we have to extend it. 
1420
1421    The number in eh_table is the code label number of the exception
1422    handler for the region. This is added by add_eh_table_entry and
1423    used by output_exception_table_entry.  */
1424
1425 static int *eh_table;
1426 static int eh_table_size;
1427 static int eh_table_max_size;
1428
1429 /* Note the need for an exception table entry for region N.  If we
1430    don't need to output an explicit exception table, avoid all of the
1431    extra work.
1432
1433    Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
1434    N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
1435    label number of the exception handler for the region.  */
1436
1437 void
1438 add_eh_table_entry (n)
1439      int n;
1440 {
1441 #ifndef OMIT_EH_TABLE
1442   if (eh_table_size >= eh_table_max_size)
1443     {
1444       if (eh_table)
1445         {
1446           eh_table_max_size += eh_table_max_size>>1;
1447
1448           if (eh_table_max_size < 0)
1449             abort ();
1450
1451           if ((eh_table = (int *) realloc (eh_table,
1452                                            eh_table_max_size * sizeof (int)))
1453               == 0)
1454             fatal ("virtual memory exhausted");
1455         }
1456       else
1457         {
1458           eh_table_max_size = 252;
1459           eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
1460         }
1461     }
1462   eh_table[eh_table_size++] = n;
1463 #endif
1464 }
1465
1466 /* Return a non-zero value if we need to output an exception table.
1467
1468    On some platforms, we don't have to output a table explicitly.
1469    This routine doesn't mean we don't have one.  */
1470
1471 int
1472 exception_table_p ()
1473 {
1474   if (eh_table)
1475     return 1;
1476
1477   return 0;
1478 }
1479
1480 /* Output the entry of the exception table corresponding to to the
1481    exception region numbered N to file FILE. 
1482
1483    N is the code label number corresponding to the handler of the
1484    region.  */
1485
1486 static void
1487 output_exception_table_entry (file, n)
1488      FILE *file;
1489      int n;
1490 {
1491   char buf[256];
1492   rtx sym;
1493
1494   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
1495   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1496   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1497
1498   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
1499   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1500   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1501
1502   ASM_GENERATE_INTERNAL_LABEL (buf, "L", n);
1503   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1504   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1505
1506   putc ('\n', file);            /* blank line */
1507 }
1508
1509 /* Output the exception table if we have and need one.  */
1510
1511 void
1512 output_exception_table ()
1513 {
1514   int i;
1515   extern FILE *asm_out_file;
1516
1517   if (! doing_eh (0))
1518     return;
1519
1520   exception_section ();
1521
1522   /* Beginning marker for table.  */
1523   assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1524   assemble_label ("__EXCEPTION_TABLE__");
1525
1526   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1527   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1528   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1529   putc ('\n', asm_out_file);            /* blank line */
1530
1531   for (i = 0; i < eh_table_size; ++i)
1532     output_exception_table_entry (asm_out_file, eh_table[i]);
1533
1534   free (eh_table);
1535
1536   /* Ending marker for table.  */
1537   assemble_label ("__EXCEPTION_END__");
1538   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1539   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1540   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1541   putc ('\n', asm_out_file);            /* blank line */
1542 }
1543
1544 /* Generate code to initialize the exception table at program startup
1545    time.  */
1546
1547 void
1548 register_exception_table ()
1549 {
1550   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0,
1551                      VOIDmode, 1,
1552                      gen_rtx (SYMBOL_REF, Pmode, "__EXCEPTION_TABLE__"),
1553                      Pmode);
1554 }
1555 \f
1556 /* Emit the RTL for the start of the per-function unwinder for the
1557    current function. See emit_unwinder for further information.
1558
1559    DOESNT_NEED_UNWINDER is a target-specific macro that determines if
1560    the current function actually needs a per-function unwinder or not.
1561    By default, all functions need one.  */
1562
1563 void
1564 start_eh_unwinder ()
1565 {
1566 #ifdef DOESNT_NEED_UNWINDER
1567   if (DOESNT_NEED_UNWINDER)
1568     return;
1569 #endif
1570
1571   /* If we are using the setjmp/longjmp implementation, we don't need a
1572      per function unwinder.  */
1573
1574   if (exceptions_via_longjmp)
1575     return;
1576
1577   expand_eh_region_start ();
1578 }
1579
1580 /* Emit insns for the end of the per-function unwinder for the
1581    current function.  */
1582
1583 void
1584 end_eh_unwinder ()
1585 {
1586   tree expr;
1587   rtx return_val_rtx, ret_val, label, end, insns;
1588
1589   if (! doing_eh (0))
1590     return;
1591
1592 #ifdef DOESNT_NEED_UNWINDER
1593   if (DOESNT_NEED_UNWINDER)
1594     return;
1595 #endif
1596
1597   /* If we are using the setjmp/longjmp implementation, we don't need a
1598      per function unwinder.  */
1599
1600   if (exceptions_via_longjmp)
1601     return;
1602
1603   assemble_external (eh_saved_pc);
1604
1605   expr = make_node (RTL_EXPR);
1606   TREE_TYPE (expr) = void_type_node;
1607   RTL_EXPR_RTL (expr) = const0_rtx;
1608   TREE_SIDE_EFFECTS (expr) = 1;
1609   start_sequence_for_rtl_expr (expr);
1610
1611   /* ret_val will contain the address of the code where the call
1612      to the current function occurred.  */
1613   ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
1614                                         0, hard_frame_pointer_rtx);
1615   return_val_rtx = copy_to_reg (ret_val);
1616
1617   /* Get the address we need to use to determine what exception
1618      handler should be invoked, and store it in __eh_pc.  */
1619   return_val_rtx = eh_outer_context (return_val_rtx);
1620   emit_move_insn (eh_saved_pc_rtx, return_val_rtx);
1621   
1622   /* Either set things up so we do a return directly to __throw, or
1623      we return here instead.  */
1624 #ifdef JUMP_TO_THROW
1625   emit_move_insn (ret_val, throw_libfunc);
1626 #else
1627   label = gen_label_rtx ();
1628   emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, label));
1629 #endif
1630
1631 #ifdef RETURN_ADDR_OFFSET
1632   return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
1633   if (return_val_rtx != ret_val)
1634     emit_move_insn (ret_val, return_val_rtx);
1635 #endif
1636   
1637   end = gen_label_rtx ();
1638   emit_jump (end);  
1639
1640   RTL_EXPR_SEQUENCE (expr) = get_insns ();
1641   end_sequence ();
1642
1643   expand_eh_region_end (expr);
1644
1645   emit_jump (end);
1646
1647 #ifndef JUMP_TO_THROW
1648   emit_label (label);
1649   emit_throw ();
1650 #endif
1651   
1652   expand_leftover_cleanups ();
1653
1654   emit_label (end);
1655
1656 #ifdef HAVE_return
1657   if (HAVE_return)
1658     {
1659       emit_jump_insn (gen_return ());
1660       emit_barrier ();
1661     }
1662 #endif
1663 }
1664
1665 /* If necessary, emit insns for the per function unwinder for the
1666    current function.  Called after all the code that needs unwind
1667    protection is output.  
1668
1669    The unwinder takes care of catching any exceptions that have not
1670    been previously caught within the function, unwinding the stack to
1671    the next frame, and rethrowing using the address of the current
1672    function's caller as the context of the throw.
1673
1674    On some platforms __throw can do this by itself (or with the help
1675    of __unwind_function) so the per-function unwinder is
1676    unnecessary.
1677   
1678    We cannot place the unwinder into the function until after we know
1679    we are done inlining, as we don't want to have more than one
1680    unwinder per non-inlined function.  */
1681
1682 void
1683 emit_unwinder ()
1684 {
1685   rtx insns, insn;
1686
1687   start_sequence ();
1688   start_eh_unwinder ();
1689   insns = get_insns ();
1690   end_sequence ();
1691
1692   /* We place the start of the exception region associated with the
1693      per function unwinder at the top of the function.  */
1694   if (insns)
1695     emit_insns_after (insns, get_insns ());
1696
1697   start_sequence ();
1698   end_eh_unwinder ();
1699   insns = get_insns ();
1700   end_sequence ();
1701
1702   /* And we place the end of the exception region before the USE and
1703      CLOBBER insns that may come at the end of the function.  */
1704   if (insns == 0)
1705     return;
1706
1707   insn = get_last_insn ();
1708   while (GET_CODE (insn) == NOTE
1709          || (GET_CODE (insn) == INSN
1710              && (GET_CODE (PATTERN (insn)) == USE
1711                  || GET_CODE (PATTERN (insn)) == CLOBBER)))
1712     insn = PREV_INSN (insn);
1713
1714   if (GET_CODE (insn) == CODE_LABEL
1715       && GET_CODE (PREV_INSN (insn)) == BARRIER)
1716     {
1717       insn = PREV_INSN (insn);
1718     }
1719   else
1720     {
1721       rtx label = gen_label_rtx ();
1722       emit_label_after (label, insn);
1723       insn = emit_jump_insn_after (gen_jump (label), insn);
1724       insn = emit_barrier_after (insn);
1725     }
1726     
1727   emit_insns_after (insns, insn);
1728 }
1729
1730 /* Scan the current insns and build a list of handler labels. The
1731    resulting list is placed in the global variable exception_handler_labels.
1732
1733    It is called after the last exception handling region is added to
1734    the current function (when the rtl is almost all built for the
1735    current function) and before the jump optimization pass.  */
1736
1737 void
1738 find_exception_handler_labels ()
1739 {
1740   rtx insn;
1741   int max_labelno = max_label_num ();
1742   int min_labelno = get_first_label_num ();
1743   rtx *labels;
1744
1745   exception_handler_labels = NULL_RTX;
1746
1747   /* If we aren't doing exception handling, there isn't much to check.  */
1748   if (! doing_eh (0))
1749     return;
1750
1751   /* Generate a handy reference to each label.  */
1752
1753   labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
1754   bzero ((char *) labels, (max_labelno - min_labelno) * sizeof (rtx));
1755
1756   /* Arrange for labels to be indexed directly by CODE_LABEL_NUMBER.  */
1757   labels -= min_labelno;
1758
1759   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1760     {
1761       if (GET_CODE (insn) == CODE_LABEL)
1762         if (CODE_LABEL_NUMBER (insn) >= min_labelno
1763             && CODE_LABEL_NUMBER (insn) < max_labelno)
1764           labels[CODE_LABEL_NUMBER (insn)] = insn;
1765     }
1766
1767   /* For each start of a region, add its label to the list.  */
1768
1769   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1770     {
1771       if (GET_CODE (insn) == NOTE
1772           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1773         {
1774           rtx label = NULL_RTX;
1775
1776           if (NOTE_BLOCK_NUMBER (insn) >= min_labelno
1777               && NOTE_BLOCK_NUMBER (insn) < max_labelno)
1778             {
1779               label = labels[NOTE_BLOCK_NUMBER (insn)];
1780
1781               if (label)
1782                 exception_handler_labels
1783                   = gen_rtx (EXPR_LIST, VOIDmode,
1784                              label, exception_handler_labels);
1785               else
1786                 warning ("didn't find handler for EH region %d",
1787                          NOTE_BLOCK_NUMBER (insn));
1788             }
1789           else
1790             warning ("mismatched EH region %d", NOTE_BLOCK_NUMBER (insn));
1791         }
1792     }
1793 }
1794
1795 /* Perform sanity checking on the exception_handler_labels list.
1796
1797    Can be called after find_exception_handler_labels is called to
1798    build the list of exception handlers for the current function and
1799    before we finish processing the current function.  */
1800
1801 void
1802 check_exception_handler_labels ()
1803 {
1804   rtx insn, handler;
1805
1806   /* If we aren't doing exception handling, there isn't much to check.  */
1807   if (! doing_eh (0))
1808     return;
1809
1810   /* Ensure that the CODE_LABEL_NUMBER for the CODE_LABEL entry point
1811      in each handler corresponds to the CODE_LABEL_NUMBER of the
1812      handler.  */
1813
1814   for (handler = exception_handler_labels;
1815        handler;
1816        handler = XEXP (handler, 1))
1817     {
1818       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1819         {
1820           if (GET_CODE (insn) == CODE_LABEL)
1821             {
1822               if (CODE_LABEL_NUMBER (insn)
1823                   == CODE_LABEL_NUMBER (XEXP (handler, 0)))
1824                 {
1825                   if (insn != XEXP (handler, 0))
1826                     warning ("mismatched handler %d",
1827                              CODE_LABEL_NUMBER (insn));
1828                   break;
1829                 }
1830             }
1831         }
1832       if (insn == NULL_RTX)
1833         warning ("handler not found %d",
1834                  CODE_LABEL_NUMBER (XEXP (handler, 0)));
1835     }
1836
1837   /* Now go through and make sure that for each region there is a
1838      corresponding label.  */
1839   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1840     {
1841       if (GET_CODE (insn) == NOTE
1842           && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1843               || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1844         {
1845           for (handler = exception_handler_labels;
1846                handler;
1847                handler = XEXP (handler, 1))
1848             {
1849               if (CODE_LABEL_NUMBER (XEXP (handler, 0))
1850                   == NOTE_BLOCK_NUMBER (insn))
1851                 break;
1852             }
1853           if (handler == NULL_RTX)
1854             warning ("region exists, no handler %d",
1855                      NOTE_BLOCK_NUMBER (insn));
1856         }
1857     }
1858 }
1859 \f
1860 /* This group of functions initializes the exception handling data
1861    structures at the start of the compilation, initializes the data
1862    structures at the start of a function, and saves and restores the
1863    exception handling data structures for the start/end of a nested
1864    function.  */
1865
1866 /* Toplevel initialization for EH things.  */ 
1867
1868 void
1869 init_eh ()
1870 {
1871   /* Generate rtl to reference the variable in which the PC of the
1872      current context is saved.  */
1873   tree type = build_pointer_type (make_node (VOID_TYPE));
1874
1875   eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
1876   DECL_EXTERNAL (eh_saved_pc) = 1;
1877   TREE_PUBLIC (eh_saved_pc) = 1;
1878   make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
1879   eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
1880 }
1881
1882 /* Initialize the per-function EH information.  */
1883
1884 void
1885 init_eh_for_function ()
1886 {
1887   ehstack.top = 0;
1888   ehqueue.head = ehqueue.tail = 0;
1889   catch_clauses = NULL_RTX;
1890   false_label_stack = 0;
1891   caught_return_label_stack = 0;
1892   protect_list = NULL_TREE;
1893   current_function_dhc = NULL_RTX;
1894   current_function_dcc = NULL_RTX;
1895 }
1896
1897 /* Save some of the per-function EH info into the save area denoted by
1898    P. 
1899
1900    This is currently called from save_stmt_status.  */
1901
1902 void
1903 save_eh_status (p)
1904      struct function *p;
1905 {
1906   assert (p != NULL);
1907
1908   p->ehstack = ehstack;
1909   p->ehqueue = ehqueue;
1910   p->catch_clauses = catch_clauses;
1911   p->false_label_stack = false_label_stack;
1912   p->caught_return_label_stack = caught_return_label_stack;
1913   p->protect_list = protect_list;
1914   p->dhc = current_function_dhc;
1915   p->dcc = current_function_dcc;
1916
1917   init_eh ();
1918 }
1919
1920 /* Restore the per-function EH info saved into the area denoted by P.  
1921
1922    This is currently called from restore_stmt_status.  */
1923
1924 void
1925 restore_eh_status (p)
1926      struct function *p;
1927 {
1928   assert (p != NULL);
1929
1930   protect_list = p->protect_list;
1931   caught_return_label_stack = p->caught_return_label_stack;
1932   false_label_stack = p->false_label_stack;
1933   catch_clauses = p->catch_clauses;
1934   ehqueue = p->ehqueue;
1935   ehstack = p->ehstack;
1936   current_function_dhc = p->dhc;
1937   current_function_dcc = p->dcc;
1938 }
1939 \f
1940 /* This section is for the exception handling specific optimization
1941    pass.  First are the internal routines, and then the main
1942    optimization pass.  */
1943
1944 /* Determine if the given INSN can throw an exception.  */
1945
1946 static int
1947 can_throw (insn)
1948      rtx insn;
1949 {
1950   /* Calls can always potentially throw exceptions.  */
1951   if (GET_CODE (insn) == CALL_INSN)
1952     return 1;
1953
1954   if (asynchronous_exceptions)
1955     {
1956       /* If we wanted asynchronous exceptions, then everything but NOTEs
1957          and CODE_LABELs could throw.  */
1958       if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
1959         return 1;
1960     }
1961
1962   return 0;
1963 }
1964
1965 /* Scan a exception region looking for the matching end and then
1966    remove it if possible. INSN is the start of the region, N is the
1967    region number, and DELETE_OUTER is to note if anything in this
1968    region can throw.
1969
1970    Regions are removed if they cannot possibly catch an exception.
1971    This is determined by invoking can_throw on each insn within the
1972    region; if can_throw returns true for any of the instructions, the
1973    region can catch an exception, since there is an insn within the
1974    region that is capable of throwing an exception.
1975
1976    Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
1977    calls abort if it can't find one.
1978
1979    Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
1980    correspond to the region number, or if DELETE_OUTER is NULL.  */
1981
1982 static rtx
1983 scan_region (insn, n, delete_outer)
1984      rtx insn;
1985      int n;
1986      int *delete_outer;
1987 {
1988   rtx start = insn;
1989
1990   /* Assume we can delete the region.  */
1991   int delete = 1;
1992
1993   assert (insn != NULL_RTX
1994           && GET_CODE (insn) == NOTE
1995           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1996           && NOTE_BLOCK_NUMBER (insn) == n
1997           && delete_outer != NULL);
1998
1999   insn = NEXT_INSN (insn);
2000
2001   /* Look for the matching end.  */
2002   while (! (GET_CODE (insn) == NOTE
2003             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2004     {
2005       /* If anything can throw, we can't remove the region.  */
2006       if (delete && can_throw (insn))
2007         {
2008           delete = 0;
2009         }
2010
2011       /* Watch out for and handle nested regions.  */
2012       if (GET_CODE (insn) == NOTE
2013           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2014         {
2015           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
2016         }
2017
2018       insn = NEXT_INSN (insn);
2019     }
2020
2021   /* The _BEG/_END NOTEs must match and nest.  */
2022   if (NOTE_BLOCK_NUMBER (insn) != n)
2023     abort ();
2024
2025   /* If anything in this exception region can throw, we can throw.  */
2026   if (! delete)
2027     *delete_outer = 0;
2028   else
2029     {
2030       /* Delete the start and end of the region.  */
2031       delete_insn (start);
2032       delete_insn (insn);
2033
2034       /* Only do this part if we have built the exception handler
2035          labels.  */
2036       if (exception_handler_labels)
2037         {
2038           rtx x, *prev = &exception_handler_labels;
2039
2040           /* Find it in the list of handlers.  */
2041           for (x = exception_handler_labels; x; x = XEXP (x, 1))
2042             {
2043               rtx label = XEXP (x, 0);
2044               if (CODE_LABEL_NUMBER (label) == n)
2045                 {
2046                   /* If we are the last reference to the handler,
2047                      delete it.  */
2048                   if (--LABEL_NUSES (label) == 0)
2049                     delete_insn (label);
2050
2051                   if (optimize)
2052                     {
2053                       /* Remove it from the list of exception handler
2054                          labels, if we are optimizing.  If we are not, then
2055                          leave it in the list, as we are not really going to
2056                          remove the region.  */
2057                       *prev = XEXP (x, 1);
2058                       XEXP (x, 1) = 0;
2059                       XEXP (x, 0) = 0;
2060                     }
2061
2062                   break;
2063                 }
2064               prev = &XEXP (x, 1);
2065             }
2066         }
2067     }
2068   return insn;
2069 }
2070
2071 /* Perform various interesting optimizations for exception handling
2072    code.
2073
2074    We look for empty exception regions and make them go (away). The
2075    jump optimization code will remove the handler if nothing else uses
2076    it.  */
2077
2078 void
2079 exception_optimize ()
2080 {
2081   rtx insn, regions = NULL_RTX;
2082   int n;
2083
2084   /* The below doesn't apply to setjmp/longjmp EH.  */
2085   if (exceptions_via_longjmp)
2086     return;
2087
2088   /* Remove empty regions.  */
2089   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2090     {
2091       if (GET_CODE (insn) == NOTE
2092           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2093         {
2094           /* Since scan_region will return the NOTE_INSN_EH_REGION_END
2095              insn, we will indirectly skip through all the insns
2096              inbetween. We are also guaranteed that the value of insn
2097              returned will be valid, as otherwise scan_region won't
2098              return.  */
2099           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);
2100         }
2101     }
2102 }