OSDN Git Service

* cp-tree.def (THUNK_DECL): Remove.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 May 2000 22:25:21 +0000 (22:25 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 May 2000 22:25:21 +0000 (22:25 +0000)
* cp-tree.h (DECL_THUNK_P): New macro.
(DECL_NON_THUNK_FUNCTION_P): Likewise.
(DECL_EXTERN_C_FUNCTION_P): Likewise.
(SET_DECL_THUNK_P): Likewise.
(DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
(FNADDR_FROM_VTABLE_ENTRY): Likewise.
(DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
* decl.c (decls_match): Use DECL_EXTERN_C_P.
(duplicate_decls): Likewise.
(pushdecl): Likewise.  Adjust thunk handling.
(grokfndecl): Use DECL_EXTERN_C_P.
* decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
* dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
* except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
* expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
* method.c (make_thunk): Use SET_DECL_THUNK_P.  Set
DECL_NO_STATIC_CHAIN.
(emit_thunk): Don't play games with TREE_CODE on thunks.  Don't
set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
* search.c (covariant_return_p): Remove THUNK_DECL handling.
* ir.texi: Update.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33647 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/dump.c
gcc/cp/except.c
gcc/cp/expr.c
gcc/cp/ir.texi
gcc/cp/method.c
gcc/cp/search.c

index 1e96c5c..b2b62a3 100644 (file)
@@ -1,3 +1,28 @@
+2000-05-03  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.def (THUNK_DECL): Remove.
+       * cp-tree.h (DECL_THUNK_P): New macro.
+       (DECL_NON_THUNK_FUNCTION_P): Likewise.
+       (DECL_EXTERN_C_FUNCTION_P): Likewise.
+       (SET_DECL_THUNK_P): Likewise.
+       (DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
+       (FNADDR_FROM_VTABLE_ENTRY): Likewise.
+       (DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
+       * decl.c (decls_match): Use DECL_EXTERN_C_P.
+       (duplicate_decls): Likewise.
+       (pushdecl): Likewise.  Adjust thunk handling.
+       (grokfndecl): Use DECL_EXTERN_C_P.
+       * decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
+       * dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
+       * except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
+       * expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
+       * method.c (make_thunk): Use SET_DECL_THUNK_P.  Set
+       DECL_NO_STATIC_CHAIN.
+       (emit_thunk): Don't play games with TREE_CODE on thunks.  Don't
+       set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
+       * search.c (covariant_return_p): Remove THUNK_DECL handling.
+       * ir.texi: Update.
+       
 2000-05-01  Jason Merrill  <jason@casey.cygnus.com>
 
        * tree.c (walk_tree): Set lineno.
index 30ebe45..ead42be 100644 (file)
@@ -158,28 +158,6 @@ DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0)
    expression in question.  */
 DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
 
-/* A thunk is a stub function.
-
-   A THUNK_DECL is an alternate entry point for an ordinary
-   FUNCTION_DECL.  The address of the ordinary FUNCTION_DECL is given
-   by the DECL_INITIAL, which is always an ADDR_EXPR whose operand is
-   a FUNCTION_DECL.  The job of the thunk is to adjust the `this'
-   pointer before transferring control to the FUNCTION_DECL.
-
-   A thunk may perform either, or both, of the following operations:
-
-   o Adjust the `this' pointer by a constant offset.
-   o Adjust the `this' pointer by looking up a vcall-offset
-     in the vtable.
-
-   If both operations are performed, then the constant adjument to
-   `this' is performed first.
-
-   The constant adjustment is given by THUNK_DELTA.  If the
-   vcall-offset is required, the index into the vtable is given by
-   THUNK_VCALL_OFFSET.  */
-DEFTREECODE (THUNK_DECL, "thunk_decl", 'd', 0)
-
 /* A using declaration.  DECL_INITIAL contains the specified scope.  
    This is not an alias, but is later expanded into multiple aliases.  */
 DEFTREECODE (USING_DECL, "using_decl", 'd', 0)
index 0909d95..3a4e6b3 100644 (file)
@@ -1294,19 +1294,22 @@ enum languages { lang_c, lang_cplusplus, lang_java };
   ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))     \
    == TYPE_QUAL_CONST)
 
-#define DELTA_FROM_VTABLE_ENTRY(ENTRY) \
-  (!flag_vtable_thunks ? \
-     TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \
-   : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? integer_zero_node \
+#define DELTA_FROM_VTABLE_ENTRY(ENTRY)                         \
+  (!flag_vtable_thunks ?                                       \
+     TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY))                     \
+   : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))                         \
+   ? integer_zero_node                                         \
    : build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0))
 
 /* Virtual function addresses can be gotten from a virtual function
    table entry using this macro.  */
-#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \
-  (!flag_vtable_thunks ? \
-     TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) \
-   : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? (ENTRY) \
+#define FNADDR_FROM_VTABLE_ENTRY(ENTRY)                                        \
+  (!flag_vtable_thunks ?                                               \
+     TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY))))   \
+   : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))                         \
+   ? (ENTRY)                                                           \
    : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
+
 #define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \
   (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) = (VALUE))
 #define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
@@ -2099,6 +2102,27 @@ struct lang_decl
    must be overridden by derived classes.  */
 #define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.needs_final_overrider)
 
+/* Nonzero if NODE is a thunk, rather than an ordinary function.  */
+#define DECL_THUNK_P(NODE)                     \
+  (TREE_CODE (NODE) == FUNCTION_DECL           \
+   && DECL_LANG_FLAG_7 (NODE))
+
+/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk.  */
+#define DECL_NON_THUNK_FUNCTION_P(NODE)                                \
+  (TREE_CODE (NODE) == FUNCTION_DECL && !DECL_THUNK_P (NODE))
+
+/* Nonzero if NODE is `extern "C"'.  */
+#define DECL_EXTERN_C_P(NODE) \
+  (DECL_LANGUAGE (NODE) == lang_c)
+
+/* Nonzero if NODE is an `extern "C"' function.  */
+#define DECL_EXTERN_C_FUNCTION_P(NODE) \
+  (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))
+
+/* Set DECL_THUNK_P for node.  */
+#define SET_DECL_THUNK_P(NODE) \
+  (DECL_LANG_FLAG_7 (NODE) = 1)
+
 /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
    template function.  */
 #define DECL_PRETTY_FUNCTION_P(NODE) \
@@ -2986,6 +3010,27 @@ extern int flag_new_for_scope;
 #define DECL_REALLY_EXTERN(NODE) \
   (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
 
+/* A thunk is a stub function.
+
+   A thunk is an alternate entry point for an ordinary FUNCTION_DECL.
+   The address of the ordinary FUNCTION_DECL is given by the
+   DECL_INITIAL, which is always an ADDR_EXPR whose operand is a
+   FUNCTION_DECL.  The job of the thunk is to adjust the `this'
+   pointer before transferring control to the FUNCTION_DECL.
+
+   A thunk may perform either, or both, of the following operations:
+
+   o Adjust the `this' pointer by a constant offset.
+   o Adjust the `this' pointer by looking up a vcall-offset
+     in the vtable.
+
+   If both operations are performed, then the constant adjument to
+   `this' is performed first.
+
+   The constant adjustment is given by THUNK_DELTA.  If the
+   vcall-offset is required, the index into the vtable is given by
+   THUNK_VCALL_OFFSET.  */
+
 /* An integer indicating how many bytes should be subtracted from the
    `this' pointer when this function is called.  */
 #define THUNK_DELTA(DECL) (DECL_CHECK (DECL)->decl.u1.i)
@@ -3472,8 +3517,7 @@ extern tree original_function_name;
 /* Returns non-zero iff NODE is a declaration for the global function
    `main'.  */
 #define DECL_MAIN_P(NODE)                              \
-   (TREE_CODE (NODE) == FUNCTION_DECL                  \
-    && DECL_LANGUAGE (NODE) == lang_c                  \
+   (DECL_EXTERN_C_FUNCTION_P (NODE)                     \
     && DECL_NAME (NODE) != NULL_TREE                   \
     && MAIN_NAME_P (DECL_NAME (NODE)))
 
index 3853df1..c792e74 100644 (file)
@@ -2927,8 +2927,8 @@ decls_match (newdecl, olddecl)
       tree p2 = TYPE_ARG_TYPES (f2);
 
       if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
-         && ! (DECL_LANGUAGE (newdecl) == lang_c
-               && DECL_LANGUAGE (olddecl) == lang_c))
+         && ! (DECL_EXTERN_C_P (newdecl)
+               && DECL_EXTERN_C_P (olddecl)))
        return 0;
 
       if (TREE_CODE (f1) != TREE_CODE (f2))
@@ -2937,15 +2937,17 @@ decls_match (newdecl, olddecl)
       if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
        {
          if ((! strict_prototypes_lang_c || DECL_BUILT_IN (olddecl))
-             && DECL_LANGUAGE (olddecl) == lang_c
+             && DECL_EXTERN_C_P (olddecl)
              && p2 == NULL_TREE)
            {
              types_match = self_promoting_args_p (p1);
              if (p1 == void_list_node)
                TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
            }
-         else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c
-                  && DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE)
+         else if (!strict_prototypes_lang_c 
+                  && DECL_EXTERN_C_P (olddecl)
+                  && DECL_EXTERN_C_P (newdecl)
+                  && p1 == NULL_TREE)
            {
              types_match = self_promoting_args_p (p2);
              TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
@@ -3094,8 +3096,8 @@ duplicate_decls (newdecl, olddecl)
        }
       else if (!types_match)
        {
-         if ((DECL_LANGUAGE (newdecl) == lang_c
-              && DECL_LANGUAGE (olddecl) == lang_c)
+         if ((DECL_EXTERN_C_P (newdecl)
+              && DECL_EXTERN_C_P (olddecl))
              || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
                            TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
            {
@@ -3203,8 +3205,7 @@ duplicate_decls (newdecl, olddecl)
        }
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
        {
-         if (DECL_LANGUAGE (newdecl) == lang_c
-             && DECL_LANGUAGE (olddecl) == lang_c)
+         if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl))
            {
              cp_error ("declaration of C function `%#D' conflicts with",
                        newdecl);
@@ -3801,7 +3802,7 @@ pushdecl (x)
              if (duplicate_decls (x, t))
                return t;
            }
-         else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
+         else if ((DECL_EXTERN_C_FUNCTION_P (x)
                    || DECL_FUNCTION_TEMPLATE_P (x))
                   && is_overloaded_fn (t))
            /* Don't do anything just yet. */;
@@ -3877,14 +3878,13 @@ pushdecl (x)
 
       /* If this is a function conjured up by the backend, massage it
         so it looks friendly.  */
-      if (TREE_CODE (x) == FUNCTION_DECL
-         && ! DECL_LANG_SPECIFIC (x))
+      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
        {
          retrofit_lang_decl (x);
          DECL_LANGUAGE (x) = lang_c;
        }
 
-      if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x))
+      if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
        {
          t = push_overloaded_decl (x, PUSH_LOCAL);
          if (t != x)
@@ -3980,8 +3980,7 @@ pushdecl (x)
                 the mangled name (i.e., NAME) to the DECL.  But, for
                 an `extern "C"' function, the mangled name and the
                 ordinary name are the same so we need not do this.  */
-             && !(TREE_CODE (x) == FUNCTION_DECL &&
-                  DECL_LANGUAGE (x) == lang_c))
+             && !DECL_EXTERN_C_FUNCTION_P (x))
            {
              if (TREE_CODE (x) == FUNCTION_DECL)
                my_friendly_assert
@@ -8711,7 +8710,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        {
          if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
            {
-             if (DECL_LANGUAGE (decl) == lang_c)
+             if (DECL_EXTERN_C_P (decl))
                /* Allow this; it's pretty common in C.  */;
              else
                cp_pedwarn ("non-local function `%#D' uses anonymous type",
@@ -8802,7 +8801,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
   /* Plain overloading: will not be grok'd by grokclassfn.  */
   if (! ctype && ! processing_template_decl
-      && DECL_LANGUAGE (decl) != lang_c
+      && !DECL_EXTERN_C_P (decl)
       && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
     set_mangled_name_for_decl (decl);
 
index 30bf232..fe22c3b 100644 (file)
@@ -2338,7 +2338,7 @@ mark_vtable_entries (decl)
 
       fn = TREE_OPERAND (fnaddr, 0);
       TREE_ADDRESSABLE (fn) = 1;
-      if (TREE_CODE (fn) == THUNK_DECL && DECL_EXTERNAL (fn))
+      if (DECL_THUNK_P (fn) && DECL_EXTERNAL (fn))
        {
          DECL_EXTERNAL (fn) = 0;
          emit_thunk (fn);
index dd6673c..96b0016 100644 (file)
@@ -556,7 +556,6 @@ dequeue_and_dump (di)
       break;
 
     case FUNCTION_DECL:
-    case THUNK_DECL:
       dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
       dump_child ("args", DECL_ARGUMENTS (t));
       if (DECL_EXTERNAL (t))
index dba1466..943972e 100644 (file)
@@ -1097,7 +1097,7 @@ nothrow_libfn_p (fn)
 
   if (TREE_PUBLIC (fn)
       && DECL_EXTERNAL (fn)
-      && DECL_LANGUAGE (fn) == lang_c)
+      && DECL_EXTERN_C_P (fn))
     /* OK */;
   else
     /* Can't be a C library function.  */
index c47d390..7573a79 100644 (file)
@@ -128,10 +128,6 @@ cplus_expand_expr (exp, target, tmode, modifier)
                            target, tmode, EXPAND_NORMAL);
       }
 
-    case THUNK_DECL:
-      my_friendly_assert (DECL_RTL (exp) != NULL_RTX, 20000115);
-      return DECL_RTL (exp);
-
     case THROW_EXPR:
       expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
       expand_internal_throw ();
index 882080f..9c317e4 100644 (file)
@@ -885,21 +885,6 @@ contains the instantiations.  The @code{TREE_VALUE} of each node is an
 instantiation of the class.  The @code{DECL_TEMPLATE_SPECIALIZATIONS}
 contains partial specializations of the class.
 
-@item THUNK_DECL
-
-These nodes represent stub code that adjusts the @code{this} pointer and
-then jumps to another function.  When the jumped-to function returns,
-control is transferred directly to the caller, without returning to the
-thunk.  The first parameter to the thunk is always the @code{this}
-pointer; the thunk should add @code{THUNK_DELTA} to this value.  (The
-@code{THUNK_DELTA} is an @code{int}, not an @code{INTEGER_CST}.)  Then,
-the thunk should jump to the location given by @code{DECL_INITIAL}; this
-will always be an expression for the address of a function.  
-
-You can use @code{DECL_ASSEMBLER_NAME}, @code{TREE_PUBLIC}, and
-@code{DECL_ARGUMENTS} with a @code{THUNK_DECL}, just as with a
-@code{FUNCTION_DECL}.
-
 @item USING_DECL
 
 Back-ends can safely ignore these nodes.
@@ -1044,6 +1029,19 @@ function.
 This predicate holds if the function is a file-scope finalization
 function.
 
+@item DECL_THUNK_P
+This predicate holds if the function is a thunk.
+
+These functions represent stub code that adjusts the @code{this} pointer
+and then jumps to another function.  When the jumped-to function
+returns, control is transferred directly to the caller, without
+returning to the thunk.  The first parameter to the thunk is always the
+@code{this} pointer; the thunk should add @code{THUNK_DELTA} to this
+value.  (The @code{THUNK_DELTA} is an @code{int}, not an
+@code{INTEGER_CST}.)  Then, the thunk should jump to the location given
+by @code{DECL_INITIAL}; this will always be an expression for the
+address of a function.
+
 @item GLOBAL_INIT_PRIORITY
 If either @code{DECL_GLOBAL_CTOR_P} or @code{DECL_GLOBAL_DTOR_P} holds,
 then this gives the initialization priority for the function.  The
@@ -1895,7 +1893,7 @@ by the last @code{EXPR_STMT} in the outermost scope of the
 @end example
 the value is @code{3} while in:
 @example
-(@{ if (x) { 3; } @})
+(@{ if (x) @{ 3; @} @})
 @end example
 (represented by a nested @code{COMPOUND_STMT}), there is no value.  If
 the @code{STMT_EXPR} does not yield a value, it's type will be
index ff1237e..07173d7 100644 (file)
@@ -2046,7 +2046,7 @@ make_thunk (function, delta, vcall_index)
   thunk_id = get_identifier (obstack_base (&scratch_obstack));
 
   thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
-  if (thunk && TREE_CODE (thunk) != THUNK_DECL)
+  if (thunk && !DECL_THUNK_P (thunk))
     {
       cp_error ("implementation-reserved name `%D' used", thunk_id);
       thunk = NULL_TREE;
@@ -2058,7 +2058,7 @@ make_thunk (function, delta, vcall_index)
       TREE_READONLY (thunk) = TREE_READONLY (func_decl);
       TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);
       comdat_linkage (thunk);
-      TREE_SET_CODE (thunk, THUNK_DECL);
+      SET_DECL_THUNK_P (thunk);
       DECL_INITIAL (thunk) = function;
       THUNK_DELTA (thunk) = delta;
       THUNK_VCALL_OFFSET (thunk) 
@@ -2066,6 +2066,9 @@ make_thunk (function, delta, vcall_index)
       DECL_EXTERNAL (thunk) = 1;
       DECL_ARTIFICIAL (thunk) = 1;
       DECL_CONTEXT (thunk) = DECL_CONTEXT (func_decl);
+      /* Even if this thunk is a member of a local class, we don't
+        need a static chain.  */
+      DECL_NO_STATIC_CHAIN (thunk) = 1;
       /* So that finish_file can write out any thunks that need to be: */
       pushdecl_top_level (thunk);
     }
@@ -2094,8 +2097,6 @@ emit_thunk (thunk_fndecl)
   if (current_function_decl)
     abort ();
 
-  TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
-
 #ifdef ASM_OUTPUT_MI_THUNK
   if (!flag_syntax_only && vcall_offset == 0)
     {
@@ -2146,6 +2147,11 @@ emit_thunk (thunk_fndecl)
     DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;
     DECL_SAVED_FUNCTION_DATA (thunk_fndecl) = NULL;
 
+    /* The thunk itself is not a constructor or destructor, even if
+       the thing it is thunking to is.  */
+    DECL_DESTRUCTOR_P (thunk_fndecl) = 0;
+    DECL_CONSTRUCTOR_P (thunk_fndecl) = 0;
+
     push_to_top_level ();
     start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
     store_parm_decls ();
@@ -2207,8 +2213,6 @@ emit_thunk (thunk_fndecl)
     if (DECL_DEFER_OUTPUT (thunk_fndecl))
       output_inline_function (thunk_fndecl);
   }
-
-  TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
 }
 \f
 /* Code for synthesizing methods which have default semantics defined.  */
index 197a6ad..9b70d4e 100644 (file)
@@ -1989,8 +1989,7 @@ covariant_return_p (brettype, drettype)
 {
   tree binfo;
 
-  if (TREE_CODE (brettype) == FUNCTION_DECL
-      || TREE_CODE (brettype) == THUNK_DECL)
+  if (TREE_CODE (brettype) == FUNCTION_DECL)
     {
       brettype = TREE_TYPE (TREE_TYPE (brettype));
       drettype = TREE_TYPE (TREE_TYPE (drettype));