This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] C++/Debug : 'using' in DWARF



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]