home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / cp-except.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  37KB  |  1,210 lines

  1. /* Handle exceptional things in C++.
  2.    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
  3.    Contributed by Michael Tiemann (tiemann@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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. /* High-level class interface. */
  23.  
  24. #define NULL 0
  25.  
  26. /* This should be part of `ansi_opname', or at least be defined by the std.  */
  27. #define EXCEPTION_NAME_PREFIX "__ex"
  28. #define EXCEPTION_NAME_LENGTH 4
  29.  
  30. #include "config.h"
  31. #include "tree.h"
  32. #include "rtl.h"
  33. #include "cp-tree.h"
  34. #include "flags.h"
  35. /* On Suns this can get you to the right definition if you
  36.    set the right value for TARGET.  */
  37. #include <setjmp.h>
  38. #ifdef sequent
  39. /* Can you believe they forgot this?  */
  40. #define _JBLEN 11
  41. #endif
  42.  
  43. #ifndef _JBLEN
  44. #define _JBLEN (sizeof(jmp_buf)/sizeof(int))
  45. #endif
  46.  
  47. void init_exception_processing ();
  48. void init_exception_processing_1 ();
  49.  
  50. /* If non-zero, a VAR_DECL whose cleanup will cause a throw to the
  51.    next exception handler.  Its value says whether to throw or not.
  52.    In the case of functions which do not issue a RAISE, it should be
  53.    possible to optimize away this VAR_DECL (and overhead associated
  54.    with it).  */
  55. tree exception_throw_decl;
  56. /* Use this to know that we did not set `exception_throw_decl',
  57.    until GCC optimizer is smart enough to figure it out for itself.  */
  58. int sets_exception_throw_decl;
  59.  
  60. /* The exception `type' currently in scope, or NULL_TREE if none.  */
  61. tree current_exception_type;
  62.  
  63. /* The exception handler object for the given scope.  */
  64. tree current_exception_decl;
  65. rtx current_exception_name_as_rtx;
  66. rtx current_exception_parms_as_rtx;
  67.  
  68. /* The ``object'' view of the current exception parameters.
  69.    We cast up from the `parms' field to `current_exception_type'.  */
  70. tree current_exception_object;
  71.  
  72. /* Cache `setjmp', `longjmp', `raise_exception', and `unhandled_exception'
  73.    after default conversion.  Maybe later they will get built-in.  */
  74. static tree BISJ, BILJ, BIR, BIUE;
  75.  
  76. /* Local variables which give the appearance that exception
  77.    handling is part of the language and the execution model.  */
  78.  
  79. /* The type of the exception handler stack.  */
  80. static tree EHS_type;
  81.  
  82. /* The global handler stack.  */
  83. tree EHS_decl;
  84.  
  85. /* Cached component refs to fields of `EHS_decl'.  */
  86. static tree EHS_prev, EHS_handler, EHS_parms, EHS_name;
  87. static rtx EHS_parms_as_rtx, EHS_name_as_rtx;
  88.  
  89. /* The parameter names of this exception type.  */
  90.  
  91. static tree last_exception_fields;
  92. static tree last_exception_field_types;
  93.  
  94. /* When ID is VOID_TYPE_NODE, it means ``raise all''.
  95.    Cannot be inline, since it uses `alloca', and that
  96.    breaks code which pushes the result of this function
  97.    on the stack.  */
  98. static tree
  99. exception_object_name (prefix, id)
  100.      tree prefix;
  101.      tree id;
  102. {
  103.   /* First, cons up the `name' of this exception.  */
  104.   char *name;
  105.   int length = (id == void_type_node ? 3 : IDENTIFIER_LENGTH (id)) + EXCEPTION_NAME_LENGTH;
  106.  
  107.   if (prefix)
  108.     length += IDENTIFIER_LENGTH (prefix) + 2;
  109.  
  110.   name = (char *)alloca (length);
  111.   strcpy (name, EXCEPTION_NAME_PREFIX);
  112.   length = EXCEPTION_NAME_LENGTH;
  113.   if (prefix)
  114.     {
  115.       strcpy (name + length, IDENTIFIER_POINTER (prefix));
  116.       name[length + IDENTIFIER_LENGTH (prefix)] = JOINER;
  117.       length += IDENTIFIER_LENGTH (prefix) + 1;
  118.     }
  119.   if (id == void_type_node)
  120.     strcpy (name + length, "all");
  121.   else
  122.     strcpy (name + length, IDENTIFIER_POINTER (id));
  123.   return get_identifier (name);
  124. }
  125.  
  126. tree
  127. lookup_exception_cname (ctype, cname, raise_id)
  128.      tree ctype, cname;
  129.      tree raise_id;
  130. {
  131.   tree this_cname = TREE_PURPOSE (raise_id);
  132.   if (this_cname == NULL_TREE)
  133.     {
  134.       if (cname)
  135.     {
  136.       tree name = TREE_VALUE (raise_id);
  137.       if (purpose_member (name, CLASSTYPE_TAGS (ctype)))
  138.         this_cname = cname;
  139.     }
  140.     }
  141.   else if (this_cname == void_type_node)
  142.     this_cname = NULL_TREE;
  143.   else if (TREE_CODE (this_cname) != IDENTIFIER_NODE)
  144.     {
  145.       sorry ("multiple scope refs in `cplus_expand_raise_stmt'");
  146.       this_cname = error_mark_node;
  147.     }
  148.   return this_cname;
  149. }
  150.  
  151. tree
  152. lookup_exception_tname (oname)
  153.      tree oname;
  154. {
  155.   return get_identifier (IDENTIFIER_POINTER (oname) + EXCEPTION_NAME_LENGTH);
  156. }
  157.  
  158. tree
  159. lookup_exception_object (cname, name, complain)
  160.      tree cname, name;
  161.      int complain;
  162. {
  163.   tree oname;
  164.   tree decl;
  165.  
  166.   if (cname == void_type_node)
  167.     cname = NULL_TREE;
  168.   else if (cname && TREE_CODE (cname) != IDENTIFIER_NODE)
  169.     {
  170.       sorry ("multiple scope refs in `lookup_exception_object'");
  171.       cname = NULL_TREE;
  172.     }
  173.   oname = exception_object_name (cname, name);
  174.   decl = IDENTIFIER_GLOBAL_VALUE (oname);
  175.   if (decl == NULL_TREE || TREE_CODE (decl) != VAR_DECL)
  176.     {
  177.       if (complain)
  178.     {
  179.       push_obstacks_nochange ();
  180.  
  181.       if (cname)
  182.         error ("no exception name object for name `%s::%s'",
  183.            IDENTIFIER_POINTER (cname),
  184.            IDENTIFIER_POINTER (name));
  185.       else
  186.         error ("no exception name object for name `%s'",
  187.            IDENTIFIER_POINTER (name));
  188.       end_temporary_allocation ();
  189.       /* Avoid further error messages.  */
  190.       pushdecl_top_level (build_lang_field_decl (VAR_DECL,
  191.                              exception_object_name (cname, name),
  192.                              error_mark_node));
  193.       pop_obstacks ();
  194.     }
  195.       return NULL_TREE;
  196.     }
  197.   return decl;
  198. }
  199.  
  200. tree
  201. lookup_exception_type (ctype, cname, raise_id)
  202.      tree ctype, cname;
  203.      tree raise_id;
  204. {
  205.   tree name = TREE_VALUE (raise_id);
  206.   tree purpose = TREE_PURPOSE (raise_id);
  207.  
  208.   if (cname && purpose == NULL_TREE)
  209.     purpose = cname;
  210.  
  211.   if (purpose && purpose != void_type_node)
  212.     {
  213.       tree link = NULL_TREE;
  214.  
  215.       if (TREE_CODE (purpose) != IDENTIFIER_NODE)
  216.     {
  217.       sorry ("multiple scope refs in `lookup_exception_type'");
  218.       TREE_PURPOSE (raise_id) = NULL_TREE;
  219.       return NULL_TREE;
  220.     }
  221.       if (! is_aggr_typedef (purpose, 1))
  222.     return NULL_TREE;
  223.       ctype = IDENTIFIER_TYPE_VALUE (purpose);
  224.       link = purpose_member (name, CLASSTYPE_TAGS (ctype));
  225.       if (link)
  226.     return TREE_VALUE (link);
  227.     }
  228.  
  229.   ctype = lookup_name (name, 1);
  230.   if (ctype && TREE_CODE (ctype) == TYPE_DECL)
  231.     ctype = TREE_TYPE (ctype);
  232.   if (ctype && TREE_CODE (ctype) == RECORD_TYPE
  233.       && CLASSTYPE_DECLARED_EXCEPTION (ctype))
  234.     return ctype;
  235.   return NULL_TREE;
  236. }
  237.  
  238. tree
  239. finish_exception (e, list_of_fieldlists)
  240.      tree e;
  241.      tree list_of_fieldlists;
  242. {
  243.   tree parmtypes = NULL_TREE, name_field;
  244.   tree cname = TYPE_NAME (e);
  245.  
  246.   if (TREE_CODE (cname) == TYPE_DECL)
  247.     cname = DECL_NAME (cname);
  248.  
  249.   if (last_exception_fields)
  250.     error ("cannot declare exceptions within exceptions");
  251.   if (list_of_fieldlists && ! ANON_AGGRNAME_P (cname))
  252.     error_with_aggr_type (e, "exception name `%s' must follow body declaration");
  253.   if (list_of_fieldlists)
  254.     {
  255.       tree prev, field;
  256.  
  257.       /* Note: no public, private, or protected allowed.  */
  258.       if (TREE_CHAIN (list_of_fieldlists))
  259.     error ("visibility declarations invalid in exception declaration");
  260.       else if (TREE_PURPOSE (list_of_fieldlists) != (tree)visibility_default)
  261.     error ("visibility declarations invalid in exception declaration");
  262.       TREE_PURPOSE (list_of_fieldlists) = (tree)visibility_default;
  263.  
  264.       /* Note also: no member function declarations allowed.  */
  265.       for (prev = 0, field = TREE_VALUE (list_of_fieldlists);
  266.        field; prev = field, field = TREE_CHAIN (field))
  267.     {
  268.       switch (TREE_CODE (field))
  269.         {
  270.         case FIELD_DECL:
  271.           /* ok.  */
  272.           parmtypes = tree_cons (NULL_TREE, TREE_TYPE (field), parmtypes);
  273.           continue;
  274.         case FUNCTION_DECL:
  275.           error_with_decl (field, "declaration of function `%s' in exception invalid");
  276.           break;
  277.         case VAR_DECL:
  278.           if (TREE_STATIC (