This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[RFA] Patch for supportinf DW_TAG_module / FORTRAN modules


Hi,

The patch below provides support for DW_TAG_module which is used to
represent FORTRAN modules, and possibly other language constructs, such
as C++ namespaces. The patch basically provides support for a module as
a C++ class with static members and functions.

2002-07-16  Petr Sorfa <petrs@caldera.com>

        * dwarf2read.c (dwarf2_update_pc_bounds): New function
        that updates a die's low and high pc bound. Used to
        remedy possible inconsistencies between ELF and DWARF
        information.
        (dwarf2_get_child_pc_bounds): New function that
        calculates the scope bounds of a die's children.
        (dwarf2_add_member_fn): Added a new argument that holds
        a parent die's tag type. Used to determine whether
        a child die's parent is a module and treat the child
        die as a static.
        (scan_partial_symbol): Support the DW_TAG_module tag.
        (add_partial_symbol): Support the DW_TAG_module tag.
        (process_die): Supports the DW_TAG_module tag by
        treating it as a structure scope.
        (read_file_scope): Moved  and enhanced some of the code
         to create the new dwarf2_get_child_pc_bounds()
        function.
        (read_structure_scope): Now supports the DW_TAG_module
        tag as a class and handles module variables and
        functions/subroutines as static members.
        (new_symbol): Now supports the DW_TAG_module tag and
        adds a module symbol to the global symbol list.
        (read_die_type): Now supports the DW_TAG_module tag
        as a structure scope.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.62
diff -c -p -r1.62 dwarf2read.c
*** dwarf2read.c	12 Jul 2002 19:55:10 -0000	1.62
--- dwarf2read.c	16 Jul 2002 20:19:30 -0000
*************** static void read_func_scope (struct die_
*** 793,801 ****
--- 793,809 ----
  static void read_lexical_block_scope (struct die_info *, struct objfile *,
  				      const struct comp_unit_head *);
  
+ static void dwarf2_update_pc_bounds (struct die_info *,
+                                      CORE_ADDR, CORE_ADDR,
+                                      const struct comp_unit_head *);
+ 
  static int dwarf2_get_pc_bounds (struct die_info *,
  				 CORE_ADDR *, CORE_ADDR *, struct objfile *);
  
+ static void dwarf2_get_child_pc_bounds (struct die_info *, CORE_ADDR *,
+ 			                CORE_ADDR *, struct objfile *,
+                                         const struct comp_unit_head *);
+ 
  static void dwarf2_add_field (struct field_info *, struct die_info *,
  			      struct objfile *, const struct comp_unit_head *);
  
*************** static void dwarf2_attach_fields_to_type
*** 803,809 ****
  					  struct type *, struct objfile *);
  
  static void dwarf2_add_member_fn (struct field_info *,
! 				  struct die_info *, struct objfile *objfile,
  				  const struct comp_unit_head *);
  
  static void dwarf2_attach_fn_fields_to_type (struct field_info *,
--- 811,818 ----
  					  struct type *, struct objfile *);
  
  static void dwarf2_add_member_fn (struct field_info *,
! 				  struct die_info *, unsigned int,
!                                   struct objfile *objfile,
  				  const struct comp_unit_head *);
  
  static void dwarf2_attach_fn_fields_to_type (struct field_info *,
*************** scan_partial_symbols (char *info_ptr, st
*** 1325,1330 ****
--- 1334,1342 ----
  		    }
  		}
  	      break;
+             case DW_TAG_module:
+ 		  add_partial_symbol (&pdi, objfile, cu_header);
+               break;
  	    case DW_TAG_variable:
  	    case DW_TAG_typedef:
  	    case DW_TAG_class_type:
*************** add_partial_symbol (struct partial_die_i
*** 1454,1459 ****
--- 1466,1472 ----
  			   &objfile->static_psymbols,
  			   0, (CORE_ADDR) 0, cu_language, objfile);
        break;
+     case DW_TAG_module:
      case DW_TAG_class_type:
      case DW_TAG_structure_type:
      case DW_TAG_union_type:
*************** add_partial_symbol (struct partial_die_i
*** 1467,1473 ****
  			   &objfile->static_psymbols,
  			   0, (CORE_ADDR) 0, cu_language, objfile);
  
!       if (cu_language == language_cplus)
  	{
  	  /* For C++, these implicitly act as typedefs as well. */
  	  add_psymbol_to_list (pdi->name, strlen (pdi->name),
--- 1480,1486 ----
  			   &objfile->static_psymbols,
  			   0, (CORE_ADDR) 0, cu_language, objfile);
  
!       if (cu_language == language_cplus || cu_language == language_fortran)
  	{
  	  /* For C++, these implicitly act as typedefs as well. */
  	  add_psymbol_to_list (pdi->name, strlen (pdi->name),
*************** process_die (struct die_info *die, struc
*** 1616,1621 ****
--- 1629,1637 ----
      {
      case DW_TAG_padding:
        break;
+     case DW_TAG_module:
+       read_structure_scope (die, objfile, cu_header);
+       break;
      case DW_TAG_compile_unit:
        read_file_scope (die, objfile, cu_header);
        break;
*************** read_file_scope (struct die_info *die, s
*** 1698,1721 ****
  
    if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
      {
!       if (die->has_children)
! 	{
! 	  child_die = die->next;
! 	  while (child_die && child_die->tag)
! 	    {
! 	      if (child_die->tag == DW_TAG_subprogram)
! 		{
! 		  CORE_ADDR low, high;
! 
! 		  if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
! 		    {
! 		      lowpc = min (lowpc, low);
! 		      highpc = max (highpc, high);
! 		    }
! 		}
! 	      child_die = sibling_die (child_die);
! 	    }
! 	}
      }
  
    /* If we didn't find a lowpc, set it to highpc to avoid complaints
--- 1714,1720 ----
  
    if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
      {
!       dwarf2_get_child_pc_bounds (die, &lowpc, &highpc, objfile, cu_header);
      }
  
    /* If we didn't find a lowpc, set it to highpc to avoid complaints
*************** read_lexical_block_scope (struct die_inf
*** 1965,1970 ****
--- 1964,2003 ----
    local_symbols = new->locals;
  }
  
+ /* Update the dwarf attribute low and high pc bounds for a die.
+    This is usually used to resolve any conflict between
+    ELF and DWARF information. */
+ static void
+ dwarf2_update_pc_bounds (struct die_info *die, CORE_ADDR lowpc,
+ 			CORE_ADDR highpc,
+                         const struct comp_unit_head *cu_header)
+ {
+   struct attribute *attr;
+   CORE_ADDR low;
+   CORE_ADDR high;
+ 
+   attr = dwarf_attr (die, DW_AT_low_pc);
+   if (attr)
+     {
+       low = DW_ADDR (attr);
+ 
+       if (low > lowpc)
+         {
+           DW_ADDR (attr) = lowpc;
+         }
+     }
+   attr = dwarf_attr (die, DW_AT_high_pc);
+   if (attr)
+     {
+       high = DW_ADDR (attr);
+ 
+       if (high < highpc)
+         {
+           DW_ADDR (attr) = highpc;
+         }
+     }
+ }
+ 
  /* Get low and high pc attributes from a die.
     Return 1 if the attributes are present and valid, otherwise, return 0.  */
  
*************** dwarf2_get_pc_bounds (struct die_info *d
*** 2006,2011 ****
--- 2039,2099 ----
    return 1;
  }
  
+ /* Calculate the pc bounds of the scope of all the die's children */
+ static void
+ dwarf2_get_child_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
+ 			    CORE_ADDR *highpc, struct objfile *objfile,
+                             const struct comp_unit_head *cu_header)
+ {
+   struct die_info *child_die;
+ 
+   if (die->has_children)
+     {
+       child_die = die->next;
+       while (child_die && child_die->tag)
+         {
+ 
+           if (child_die->tag == DW_TAG_subprogram)
+             {
+               CORE_ADDR low, high;
+ 
+               if (dwarf2_get_pc_bounds (child_die, &low, &high, objfile))
+                 {
+                   *lowpc = min (*lowpc, low);
+                   *highpc = max (*highpc, high);
+                 }
+ 
+               /* Now check its children as well. This is for cases in
+                  FORTRAN 95 where a CONTAINS scope is a child of the
+                  main subprogram, but its low and high pc are outside
+                  of the main subprogram's low and high pc. */
+               dwarf2_get_child_pc_bounds (child_die, &low, &high, objfile,
+                                           cu_header);
+ 
+               *lowpc = min (*lowpc, low);
+               *highpc = max (*highpc, high);
+ 
+               /* Need to update the pc bounds for the enclosing
+                  subprogram to prevent gdb from moaning about
+                  inner blocks being outside the scope of the enclosing
+                  blocks. FIXME? FIX compiler? */
+               dwarf2_update_pc_bounds (child_die, low, high, cu_header);
+             }
+           else if (child_die->tag == DW_TAG_module)
+             {
+               CORE_ADDR low, high;
+ 
+               dwarf2_get_child_pc_bounds (child_die, &low, &high, objfile,
+                                           cu_header);
+ 
+               *lowpc = min (*lowpc, low);
+               *highpc = max (*highpc, high);
+             }
+           child_die = sibling_die (child_die);
+         }
+     }
+ }
+ 
  /* Add an aggregate field to the field list.  */
  
  static void
*************** dwarf2_attach_fields_to_type (struct fie
*** 2255,2260 ****
--- 2343,2349 ----
  
  static void
  dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
+ 		      unsigned int parent_tag,
  		      struct objfile *objfile,
  		      const struct comp_unit_head *cu_header)
  {
*************** dwarf2_add_member_fn (struct field_info 
*** 2337,2342 ****
--- 2426,2435 ----
           from read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
        if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
  	fnp->voffset = VOFFSET_STATIC;
+       
+       /* If the parent tag is a module, treat all functions as static */
+       if (parent_tag == DW_TAG_module)
+         fnp->voffset = VOFFSET_STATIC;
      }
    else
      complain (&dwarf2_missing_member_fn_type_complaint, physname);
*************** read_structure_scope (struct die_info *d
*** 2465,2470 ****
--- 2558,2570 ----
      {
        TYPE_CODE (type) = TYPE_CODE_UNION;
      }
+   else if (die->tag == DW_TAG_module)
+     {
+       /* Handle the FORTRAN module as a C++ class with static entries */
+       TYPE_CODE (type) = TYPE_CODE_CLASS;
+       ALLOCATE_CPLUS_STRUCT_TYPE (type);
+       TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_CLASS;
+     }
    else
      {
        /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
*************** read_structure_scope (struct die_info *d
*** 2505,2518 ****
  	    }
  	  else if (child_die->tag == DW_TAG_variable)
  	    {
! 	      /* C++ static member.  */
  	      dwarf2_add_field (&fi, child_die, objfile, cu_header);
  	    }
  	  else if (child_die->tag == DW_TAG_subprogram)
  	    {
! 	      /* C++ member function. */
  	      process_die (child_die, objfile, cu_header);
! 	      dwarf2_add_member_fn (&fi, child_die, objfile, cu_header);
  	    }
  	  else if (child_die->tag == DW_TAG_inheritance)
  	    {
--- 2605,2623 ----
  	    }
  	  else if (child_die->tag == DW_TAG_variable)
  	    {
! 	      /* C++ static member or FORTRAN 95 module variable.  */
!               if (die->tag == DW_TAG_module)
!                 {
!                   /* Adding fortran module variable */
! 	          child_die->tag = DW_TAG_variable;
!                 }
  	      dwarf2_add_field (&fi, child_die, objfile, cu_header);
  	    }
  	  else if (child_die->tag == DW_TAG_subprogram)
  	    {
! 	      /* C++ member / FORTRAN 95 module function. */
  	      process_die (child_die, objfile, cu_header);
! 	      dwarf2_add_member_fn (&fi, child_die, die->tag, objfile, cu_header);
  	    }
  	  else if (child_die->tag == DW_TAG_inheritance)
  	    {
*************** new_symbol (struct die_info *die, struct
*** 4815,4820 ****
--- 4920,4929 ----
  	     interest in this information, so just ignore it for now.
  	     (FIXME?) */
  	  break;
+ 	case DW_TAG_module:
+ 	  SYMBOL_CLASS (sym) = LOC_STATIC;
+ 	  add_symbol_to_list (sym, &global_symbols);
+           break;
  	case DW_TAG_class_type:
  	case DW_TAG_structure_type:
  	case DW_TAG_union_type:
*************** read_type_die (struct die_info *die, str
*** 5075,5080 ****
--- 5184,5193 ----
  {
    switch (die->tag)
      {
+     case DW_TAG_module:
+       /* Read the module scope a structure. */
+       read_structure_scope (die, objfile, cu_header);
+       break;
      case DW_TAG_class_type:
      case DW_TAG_structure_type:
      case DW_TAG_union_type:

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