public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] C++/Debug : 'using' in DWARF
@ 2003-12-04 20:01 Devang Patel
  0 siblings, 0 replies; only message in thread
From: Devang Patel @ 2003-12-04 20:01 UTC (permalink / raw)
  To: gcc mailing list


Right now, GCC does not emit debugging info, in DWARF, for 'using'
declarations and 'using' directives.  One approach is to  educate
lang independent code about C++ specific USING_STMT nodes.  DWARF
generator does not want to about  USING_STMTs.  Fortran front-end
may not use USING_STMT but use something else for use statements.

Another approach,  for which I am requesting feedback,  is to use
new debug hooks to handle imported modules and declarations. I am
including small code snippet that uses new debug hooks. It is not
a complete patch.  It sits on top of Dan's namespace  patch in my
local source tree. Using this patch I am  able to build  compiler
on linux-x86. In the small example I tried by hand,  dwarf output
is correct for using statements.

If this approach looks good then I will complete testing and prepare
patch. I also plan to use similar approach to emit DW_TAG_try_block
and DW_TAG_catch_block.

thoughts?
-
Devang


Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.121
diff -Idpatel.pbxuser -c -3 -p -r1.121 parser.c
*** cp/parser.c 14 Nov 2003 18:37:36 -0000      1.121
--- cp/parser.c 4 Dec 2003 18:31:22 -0000
***************
*** 34,39 ****
--- 34,40 ----
   #include "diagnostic.h"
   #include "toplev.h"
   #include "output.h"
+ #include "debug.h"



   /* The lexer.  */
*************** cp_parser_using_declaration (cp_parser*
*** 9101,9106 ****
--- 9102,9123 ----

     /* Look for the final `;'.  */
     cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+   /* Emit debugging info.  */
+   if (is_overloaded_fn (decl))
+     {
+       /* using Foo::bar and 'bar' is overloaded function.
+        Emit DW_TAG_imported_declaration for all.  */
+       tree f;
+       for (f = decl; f ; f = OVL_CHAIN (f))
+       (*debug_hooks->imported_module_or_decl) (OVL_FUNCTION (f),
+                                        current_namespace,
+                                                2 /* 2 = imported_decl 
*/);
+     }
+   else
+     (*debug_hooks->imported_module_or_decl) (decl,
+                                            current_namespace,
+                                            2 /* 2 = imported_decl */);
+
   }

   /* Parse a using-directive.
*************** cp_parser_using_directive (cp_parser* pa
*** 9134,9139 ****
--- 9151,9160 ----
     parse_using_directive (namespace_decl, attribs);
     /* Look for the final `;'.  */
     cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+   /* Emit debugging info.  */
+   (*debug_hooks->imported_module_or_decl) (namespace_decl,
+                                          current_namespace,
+                                          1 /* 1 = imported_module */);
   }

   /* Parse an asm-definition.
Index: debug.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/debug.h,v
retrieving revision 1.15
diff -Idpatel.pbxuser -c -3 -p -r1.15 debug.h
*** debug.h     6 Jul 2003 18:59:38 -0000       1.15
--- debug.h     4 Dec 2003 18:31:22 -0000
*************** struct gcc_debug_hooks
*** 89,94 ****
--- 89,97 ----
        compilation proper has finished.  */
     void (* global_decl) (tree decl);

+   /* Debug information for imported modules.  */
+   void (* imported_module_or_decl) (tree decl, tree context, int i);
+
     /* DECL is an inline function, whose body is present, but which is
        not being output at this point.  */
     void (* deferred_inline_function) (tree decl);
*************** extern void debug_nothing_int_charstar (
*** 116,121 ****
--- 119,125 ----
   extern void debug_nothing_int (unsigned int);
   extern void debug_nothing_int_int (unsigned int, unsigned int);
   extern void debug_nothing_tree (tree);
+ extern void debug_nothing_tree_tree_int (tree, tree, int);
   extern bool debug_true_tree (tree);
   extern void debug_nothing_rtx (rtx);

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.463
diff -Idpatel.pbxuser -c -3 -p -r1.463 dwarf2out.c
*** dwarf2out.c 17 Nov 2003 17:48:59 -0000      1.463
--- dwarf2out.c 4 Dec 2003 18:31:22 -0000
*************** Software Foundation, 59 Temple Place - S
*** 65,70 ****
--- 65,71 ----
   #include "langhooks.h"
   #include "hashtab.h"
   #include "cgraph.h"
+ #include "input.h"

   #ifdef DWARF2_DEBUGGING_INFO
   static void dwarf2out_source_line (unsigned int, const char *);
*************** static void dwarf2out_begin_block (unsig
*** 3233,3238 ****
--- 3234,3240 ----
   static void dwarf2out_end_block (unsigned, unsigned);
   static bool dwarf2out_ignore_block (tree);
   static void dwarf2out_global_decl (tree);
+ static void dwarf2out_imported_module_or_decl (tree, tree, int);
   static void dwarf2out_abstract_function (tree);

   /* The debug hooks structure.  */
*************** const struct gcc_debug_hooks dwarf2_debu
*** 3256,3261 ****
--- 3258,3264 ----
     debug_nothing_int,          /* end_function */
     dwarf2out_decl,             /* function_decl */
     dwarf2out_global_decl,
+   dwarf2out_imported_module_or_decl,
     debug_nothing_tree,         /* deferred_inline_function */
     /* The DWARF 2 backend tries to reduce debugging bloat by not
        emitting the abstract description of inline functions until
*************** dwarf_tag_name (unsigned int tag)
*** 4052,4057 ****
--- 4060,4069 ----
         return "DW_TAG_variable";
       case DW_TAG_volatile_type:
         return "DW_TAG_volatile_type";
+     case DW_TAG_namespace:
+       return "DW_TAG_namespace";
+     case DW_TAG_imported_module:
+       return "TW_TAG_imported_module";
       case DW_TAG_MIPS_loop:
         return "DW_TAG_MIPS_loop";
       case DW_TAG_format_label:
*************** dwarf2out_global_decl (tree decl)
*** 11962,11967 ****
--- 12067,12146 ----
       dwarf2out_decl (decl);
   }

+ /* Output debug information for imported module.
+   module_or_decl value decides following:
+   1 = Emit DW_TAG_imported_module
+   2 = Emit DW_TAG_imported_declaration.  */
+
+ static void
+ dwarf2out_imported_module_or_decl (tree decl, tree context, int 
module_or_decl)
+ {
+   dw_die_ref imported_die, at_import_die;
+   dw_die_ref scope_die;
+   unsigned file_index;
+
+   if (!decl || !context)
+     abort ();
+
+   scope_die = lookup_decl_die (context);
+   if (!scope_die)
+     {
+       if (DECL_CONTEXT (context))
+       {
+         gen_decl_die (context, comp_unit_die);
+         scope_die = lookup_decl_die (context);
+         if (!scope_die)
+           abort();
+       }
+       else
+       scope_die = comp_unit_die;
+     }
+
+   if (module_or_decl == 1)
+     imported_die = new_die (DW_TAG_imported_module, scope_die, 
context);
+   else if (module_or_decl == 2)
+     imported_die = new_die (DW_TAG_imported_declaration, scope_die, 
context);
+   else
+     abort ();
+
+   file_index = lookup_filename (input_filename);
+   add_AT_unsigned (imported_die, DW_AT_decl_file, file_index);
+   add_AT_unsigned (imported_die, DW_AT_decl_line, input_line);
+
+   /* Use original type for TYPE_DECL.  */
+   if (TREE_CODE (decl) == TYPE_DECL)
+     {
+       tree type = DECL_ORIGINAL_TYPE (decl);
+
+       if (!type)
+       type = TREE_TYPE (decl);
+
+       at_import_die = lookup_type_die (type);
+       if (!at_import_die)
+       {
+         /* Attempt to force out type die.  */
+         dwarf2out_decl (decl);
+         at_import_die = lookup_type_die (type);
+         if (!at_import_die)
+           abort();
+       }
+     }
+   else
+     {
+       at_import_die = lookup_decl_die (decl);
+       if (!at_import_die)
+       {
+         /* Attempt to force out decl die.  */
+         dwarf2out_decl (decl);
+         at_import_die = lookup_decl_die (decl);
+         if (!at_import_die)
+           abort();
+       }
+     }
+   add_AT_die_ref (imported_die, DW_AT_import, at_import_die);
+ }
+
+
   /* Write the debugging output for DECL.  */

   void
*************** dwarf2out_decl (tree decl)
*** 12007,12014 ****
          inline" functions as DECL_EXTERNAL, but we need to generate 
DWARF for
          them anyway. Note that the C++ front-end also plays some 
similar games
          for inline function definitions appearing within include files 
which
!        also contain `#pragma interface' pragmas.  */
!       if (DECL_INITIAL (decl) == NULL_TREE)
         return;

         /* If we're a nested function, initially use a parent of NULL; 
if we're
--- 12186,12198 ----
          inline" functions as DECL_EXTERNAL, but we need to generate 
DWARF for
          them anyway. Note that the C++ front-end also plays some 
similar games
          for inline function definitions appearing within include files 
which
!        also contain `#pragma interface' pragmas.
!
!        However we want to emit DIEs to represent mere function 
declarations,
!        if they are class members. We check DECL_CONTEXT to find class 
members.
!       */
!
!       if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == 
NULL_TREE)
         return;

         /* If we're a nested function, initially use a parent of NULL; 
if we're

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-12-04 19:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-12-04 20:01 [RFC] C++/Debug : 'using' in DWARF Devang Patel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).