class.c (finish_struct): If we're a local class in a template function, add a TAG_DEFN.
authorJason Merrill <jason@casey.cygnus.com>
Tue, 16 Nov 1999 01:37:39 +0000 (01:37 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 16 Nov 1999 01:37:39 +0000 (20:37 -0500)
        * class.c (finish_struct): If we're a local class in a template
        function, add a TAG_DEFN.
        * pt.c (lookup_template_class): If this is a local class in a
        template function, call pushtag.
        (tsubst_expr, case TAG_DEFN): Handle classes, too.

        Emit debug info with the vtable.
        * search.c (maybe_suppress_debug_info): New function...
        * class.c (finish_struct_1): ...split out from here.
        * cp-tree.h: Declare it.
        * decl2.c (finish_vtable_vardecl): Override TYPE_DECL_SUPPRESS_DEBUG
        if we're writing out the vtable.
        * decl.c, search.c (dfs_debug_mark, dfs_debug_unmarked_p,
        note_debug_info_needed): #if 0 out.

From-SVN: r30541

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/pt.c
gcc/cp/search.c

index b7402235be9a8dba45dd10485794541fc235f3cc..cc45c1e0bda823931464e875531c7ac95458ae0c 100644 (file)
@@ -1,3 +1,20 @@
+1999-11-15  Jason Merrill  <jason@casey.cygnus.com>
+
+       * class.c (finish_struct): If we're a local class in a template
+       function, add a TAG_DEFN.
+       * pt.c (lookup_template_class): If this is a local class in a
+       template function, call pushtag.
+       (tsubst_expr, case TAG_DEFN): Handle classes, too.
+
+       Emit debug info with the vtable.
+       * search.c (maybe_suppress_debug_info): New function...
+       * class.c (finish_struct_1): ...split out from here.
+       * cp-tree.h: Declare it.
+       * decl2.c (finish_vtable_vardecl): Override TYPE_DECL_SUPPRESS_DEBUG
+       if we're writing out the vtable.
+       * decl.c, search.c (dfs_debug_mark, dfs_debug_unmarked_p, 
+       note_debug_info_needed): #if 0 out.
+
 1999-11-14  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (DECL_LOCAL_FUCNTION_P): New macro.
index a3b37f786dfb25a66c834ef5b3009e5f73ebc1a5..19bd69cf089a0666e85eb48b5a44100467a3d0a1 100644 (file)
@@ -4180,46 +4180,7 @@ finish_struct_1 (t)
   if (warn_overloaded_virtual)
     warn_hidden (t);
 
-#if 0
-  /* This has to be done after we have sorted out what to do with
-     the enclosing type.  */
-  if (write_symbols != DWARF_DEBUG)
-    {
-      /* Be smarter about nested classes here.  If a type is nested,
-        only output it if we would output the enclosing type.  */
-      if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t)))
-       DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t));
-    }
-#endif
-
-  if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG)
-    {
-      /* If the type has methods, we want to think about cutting down
-        the amount of symbol table stuff we output.  The value stored in
-        the TYPE_DECL's DECL_IGNORED_P slot is a first approximation.
-        For example, if a member function is seen and we decide to
-        write out that member function, then we can change the value
-        of the DECL_IGNORED_P slot, and the type will be output when
-        that member function's debug info is written out.
-
-        We can't do this with DWARF, which does not support name
-        references between translation units.  */
-      if (CLASSTYPE_METHOD_VEC (t))
-       {
-         /* Don't output full info about any type
-            which does not have its implementation defined here.  */
-         if (CLASSTYPE_INTERFACE_ONLY (t))
-           TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
-#if 0
-         /* XXX do something about this.  */
-         else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
-           /* Only a first approximation!  */
-           TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
-#endif
-       }
-      else if (CLASSTYPE_INTERFACE_ONLY (t))
-       TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
-    }
+  maybe_suppress_debug_info (t);
 
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (t, toplevel_bindings_p ());
@@ -4287,6 +4248,13 @@ finish_struct (t, attributes)
   else
     error ("trying to finish struct, but kicked out due to previous parse errors.");
 
+  if (processing_template_decl)
+    {
+      tree scope = current_scope ();
+      if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+       add_tree (build_min (TAG_DEFN, t));
+    }
+
   return t;
 }
 \f
index c73e86972b09274a95747b400bbe6508417c8b90..24f71c31abe9b0bf923890d57b89af2e0ce8a0a0 100644 (file)
@@ -3830,6 +3830,7 @@ extern tree init_vbase_pointers                   PROTO((tree, tree));
 extern void expand_indirect_vtbls_init         PROTO((tree, tree, tree));
 extern void clear_search_slots                 PROTO((tree));
 extern tree get_vbase_types                    PROTO((tree));
+extern void maybe_suppress_debug_info          PROTO((tree));
 extern void note_debug_info_needed             PROTO((tree));
 extern void push_class_decls                   PROTO((tree));
 extern void pop_class_decls                    PROTO((void));
index 8b5d8bd199f86724e427e438e4514ba63540ca6a..a0dbffee46cb098bb8c930920c34d7e8b0cb9be3 100644 (file)
@@ -7063,12 +7063,17 @@ layout_var_decl (decl)
       cp_error ("storage size of `%D' isn't known", decl);
       TREE_TYPE (decl) = error_mark_node;
     }
+#if 0
+  /* Keep this code around in case we later want to control debug info
+     based on whether a type is "used".  (jason 1999-11-11) */
+
   else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype))
     /* Let debugger know it should output info for this type.  */
     note_debug_info_needed (ttype);
 
   if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl))
     note_debug_info_needed (DECL_CONTEXT (decl));
+#endif
 
   if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
       && DECL_SIZE (decl) != NULL_TREE
@@ -13443,6 +13448,10 @@ finish_function (lineno, flags)
          tree ttype = target_type (fntype);
          tree parmdecl;
 
+#if 0
+         /* Keep this code around in case we later want to control debug info
+            based on whether a type is "used".  (jason 1999-11-11) */
+
          if (IS_AGGR_TYPE (ttype))
            /* Let debugger know it should output info for this type.  */
            note_debug_info_needed (ttype);
@@ -13454,6 +13463,7 @@ finish_function (lineno, flags)
                /* Let debugger know it should output info for this type.  */
                note_debug_info_needed (ttype);
            }
+#endif
        }
 
       /* Clean house because we will need to reorder insns here.  */
@@ -13643,8 +13653,13 @@ finish_function (lineno, flags)
          mark_inline_for_output (fndecl);
        }
 
+#if 0
+      /* Keep this code around in case we later want to control debug info
+        based on whether a type is "used".  (jason 1999-11-11) */
+
       if (ctype && TREE_ASM_WRITTEN (fndecl))
        note_debug_info_needed (ctype);
+#endif
 
       returns_null |= can_reach_end;
 
index 8e3d2323c360d9616272cf90b19fff760118018c..8c623fc1daa104fcc57fe2be9b4cbf5ac6c5037a 100644 (file)
@@ -2598,6 +2598,14 @@ finish_vtable_vardecl (t, data)
       if (flag_syntax_only)
        TREE_ASM_WRITTEN (vars) = 1;
 
+      /* Since we're writing out the vtable here, also write the debug 
+        info.  */
+      if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (ctype)))
+       {
+         TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (ctype)) = 0;
+         rest_of_type_compilation (ctype, toplevel_bindings_p ());
+       }
+
       return 1;
     }
   else if (!DECL_NEEDED_P (vars))
index 3d29ad70581c7e5832283becdd540d92716426b9..91a4407be7f079a15c9b8c69b8d340c8582f5a01 100644 (file)
@@ -369,7 +369,7 @@ build_eh_type_type_ref (type)
 }
 
 /* This routine is called to mark all the symbols representing runtime
-   type functions in the exception table as haveing been referenced.
+   type functions in the exception table as having been referenced.
    This will make sure code is emitted for them. Called from finish_file. */
 void 
 mark_all_runtime_matches () 
index 8e2a9f241cd58e2f94623889c4febfc99aef5273..c94fffed6297158214909aa6ae6191bb8c06059c 100644 (file)
@@ -3909,10 +3909,14 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
          CLASSTYPE_GOT_SEMICOLON (t) = 1;
          SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
          TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
+
+         /* A local class.  Make sure the decl gets registered properly.  */
+         if (context == current_function_decl)
+           pushtag (DECL_NAME (template), t, 0);
        }
 
-      /* If we called start_enum above, this information will already
-        be set up.  */
+      /* If we called start_enum or pushtag above, this information
+        will already be set up.  */
       if (!TYPE_NAME (t))
        {
          TYPE_CONTEXT (t) = FROB_CONTEXT (context);
@@ -7317,8 +7321,7 @@ tsubst_expr (t, args, complain, in_decl)
     case TAG_DEFN:
       prep_stmt (t);
       t = TREE_TYPE (t);
-      if (TREE_CODE (t) == ENUMERAL_TYPE)
-       tsubst (t, args, complain, NULL_TREE);
+      tsubst (t, args, complain, NULL_TREE);
       break;
 
     default:
index 060855b4d2cf9dfc8a7629df47acba62af3f1730..6ca817164c8df20a28dd08b6a0eb7811970a8f25 100644 (file)
@@ -103,8 +103,10 @@ static tree marked_new_vtablep PROTO((tree, void *));
 static tree unmarked_new_vtablep PROTO((tree, void *));
 static tree marked_pushdecls_p PROTO((tree, void *));
 static tree unmarked_pushdecls_p PROTO((tree, void *));
+#if 0
 static tree dfs_debug_unmarkedp PROTO((tree, void *));
 static tree dfs_debug_mark PROTO((tree, void *));
+#endif
 static tree dfs_find_vbases PROTO((tree, void *));
 static tree dfs_clear_vbase_slots PROTO((tree, void *));
 static tree dfs_init_vbase_pointers PROTO((tree, void *));
@@ -2301,7 +2303,6 @@ unmarked_pushdecls_p (binfo, data)
 #if 0
 static int dfs_search_slot_nonempty_p (binfo) tree binfo;
 { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
-#endif
 
 static tree 
 dfs_debug_unmarkedp (binfo, data) 
@@ -2311,6 +2312,7 @@ dfs_debug_unmarkedp (binfo, data)
   return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) 
          ? binfo : NULL_TREE);
 }
+#endif
 
 /* The worker functions for `dfs_walk'.  These do not need to
    test anything (vis a vis marking) if they are paired with
@@ -2351,8 +2353,10 @@ dfs_unmark_new_vtable (binfo) tree binfo;
 static void
 dfs_clear_search_slot (binfo) tree binfo;
 { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
-#endif
 
+/* Keep this code around in case we later want to control debug info
+   based on whether a type is "used".  Currently, we only suppress debug
+   info if we can emit it with the vtable.  jason 1999-11-11) */
 static tree
 dfs_debug_mark (binfo, data)
      tree binfo;
@@ -2360,47 +2364,18 @@ dfs_debug_mark (binfo, data)
 {
   tree t = BINFO_TYPE (binfo);
 
-  /* Use heuristic that if there are virtual functions,
-     ignore until we see a non-inline virtual function.  */
-  tree methods = CLASSTYPE_METHOD_VEC (t);
-
   CLASSTYPE_DEBUG_REQUESTED (t) = 1;
 
-  if (methods == 0)
-    return NULL_TREE;
-
   /* If interface info is known, either we've already emitted the debug
      info or we don't need to.  */
   if (CLASSTYPE_INTERFACE_KNOWN (t))
     return NULL_TREE;
 
-  /* If debug info is requested from this context for this type, supply it.
-     If debug info is requested from another context for this type,
-     see if some third context can supply it.  */
-  if (current_function_decl == NULL_TREE
-      || DECL_CLASS_CONTEXT (current_function_decl) != t)
-    {
-      if (TREE_VEC_ELT (methods, 1))
-       methods = TREE_VEC_ELT (methods, 1);
-      else if (TREE_VEC_ELT (methods, 0))
-       methods = TREE_VEC_ELT (methods, 0);
-      else
-       methods = TREE_VEC_ELT (methods, 2);
-      methods = OVL_CURRENT (methods);
-      while (methods)
-       {
-         if (DECL_VINDEX (methods)
-             && DECL_THIS_INLINE (methods) == 0
-             && DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
-           {
-             /* Somebody, somewhere is going to have to define this
-                virtual function.  When they do, they will provide
-                the debugging info.  */
-             return NULL_TREE;
-           }
-         methods = TREE_CHAIN (methods);
-       }
-    }
+  /* If the class has virtual functions, we'll emit the debug info
+     with the vtable.  */
+  if (TYPE_VIRTUAL_P (t))
+    return NULL_TREE;
+
   /* We cannot rely on some alien method to solve our problems,
      so we must write out the debug info ourselves.  */
   TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
@@ -2408,6 +2383,7 @@ dfs_debug_mark (binfo, data)
 
   return NULL_TREE;
 }
+#endif
 \f
 struct vbase_info 
 {
@@ -2933,6 +2909,41 @@ get_vbase_types (type)
   return vbase_types;
 }
 \f
+/* Debug info for C++ classes can get very large; try to avoid
+   emitting it everywhere.
+
+   As it happens, this optimization wins even when the target supports
+   BINCL (though only slightly), so we always do it. */
+
+void
+maybe_suppress_debug_info (t)
+     tree t;
+{
+  /* We don't bother with this for dwarf1, which shouldn't be used for C++
+     anyway.  */
+  if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
+      || write_symbols == NO_DEBUG)
+    return;
+
+  /* If we already know how we're handling this class, handle debug info
+     the same way.  */
+  if (CLASSTYPE_INTERFACE_ONLY (t))
+    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
+  else if (CLASSTYPE_INTERFACE_KNOWN (t))
+    /* Don't set it.  */;
+  /* If the class has virtual functions, write out the debug info
+     along with the vtable.  */
+  else if (TYPE_VIRTUAL_P (t))
+    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
+
+  /* Otherwise, just emit the debug info normally.  */
+}
+
+#if 0
+/* Keep this code around in case we later want to control debug info
+   based on whether a type is "used".  Currently, we only suppress debug
+   info if we can emit it with the vtable.  jason 1999-11-11) */
+
 /* If we want debug info for a type TYPE, make sure all its base types
    are also marked as being potentially interesting.  This avoids
    the problem of not writing any debug info for intermediate basetypes
@@ -2952,10 +2963,9 @@ note_debug_info_needed (type)
     return;
 
   /* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
-     does not support name references between translation units.  Well, we
-     could, but that would mean putting global labels in the debug output
-     before each exported type and each of its functions and static data
-     members.  */
+     does not support name references between translation units.  It supports
+     symbolic references between translation units, but only within a single
+     executable or shared library.  */
   if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
       || write_symbols == NO_DEBUG)
     return;
@@ -2970,6 +2980,7 @@ note_debug_info_needed (type)
        note_debug_info_needed (ttype);
     }
 }
+#endif
 \f
 /* Subroutines of push_class_decls ().  */
 
@@ -3333,7 +3344,9 @@ types_overlap_p (empty_type, next_type)
   return oi.found_overlap;
 }
 
-/* Given a vtable VAR, determine which binfo it comes from.  */
+/* Given a vtable VAR, determine which binfo it comes from.
+
+   FIXME What about secondary vtables?  */
 
 tree
 binfo_for_vtable (var)