(dwarf2out_frame_debug): Handle IOR.
authorJim Wilson <wilson@gcc.gnu.org>
Mon, 16 Jun 1997 00:43:19 +0000 (17:43 -0700)
committerJim Wilson <wilson@gcc.gnu.org>
Mon, 16 Jun 1997 00:43:19 +0000 (17:43 -0700)
(struct limbo_die_struct): Define.
(TYPE_DECL_IS_STUB): Call decl_ultimate_origin if DECL_ABTRACT_ORIGIN
is set.
(limbo_die_count): Delete.
(libmo_die_list): Define.
(new_die): Add die to limbo_die_list instead of incrementing
limbo_die_count.
(add_AT_location_description): Renamed from add_location_attribute.
New parameter attr_kind.
(add_location_or_const_value_attribute, gen_subprogram_die,
add_bound_info): Change call to add_AT_location_description.
(add_bound_info): Add call to contains_placeholder_p.  Ignore
MAX_EXPR and VAR_DECL.
(add_subscript_info): Ignore the index type if it is an unnamed
integral type.
(scope_die_for): Move check for function-local tags after code setting
containing_scope, and add check for non-NULL containing_scope
(add_type_attribute): If unnamed type, use TREE_TYPE instead.
(gen_enumeration_type_die, gen_struct_or_union_type_die): Call
add_child_die if die_parent is NULL.
(gen_subprogram_die): Ifdef out DW_AT_static_link code.
(decls_for_scope): Delete decrement of limbo_die_count.
(dwarf2out_finish): Add code to traverse the limbo_die_list, and
call add_child_die if die_parent is NULL.  Delete limbo_die_count code.

From-SVN: r14248

gcc/dwarf2out.c

index 941890eb27cb28aadc33097e87fb598e4379921c..4ef451f4efe55078e08bd6f8440da76dff94ec34 100644 (file)
@@ -850,6 +850,14 @@ dwarf2out_frame_debug (insn)
          cfa_temp_value = INTVAL (src);
          break;
 
+       case IOR:
+         assert (GET_CODE (XEXP (src, 0)) == REG
+                 && REGNO (XEXP (src, 0)) == cfa_temp_reg);
+         assert (REGNO (dest) == cfa_temp_reg);
+         assert (GET_CODE (XEXP (src, 1)) == CONST_INT);
+         cfa_temp_value |= INTVAL (XEXP (src, 1));
+         break;
+
        default:
          abort ();
        }
@@ -1630,6 +1638,14 @@ typedef struct pubname_struct
 }
 pubname_entry;
 
+/* The limbo die list structure.  */
+typedef struct limbo_die_struct
+{
+  dw_die_ref die;
+  struct limbo_die_struct *next;
+}
+limbo_die_node;
+
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
 #define ASM_COMMENT_START ";#"
@@ -1649,7 +1665,12 @@ pubname_entry;
   (DECL_NAME (decl) == NULL_TREE                       \
    || (DECL_ARTIFICIAL (decl)                          \
        && is_tagged_type (TREE_TYPE (decl))            \
-       && decl == TYPE_STUB_DECL (TREE_TYPE (decl))))
+       && ((decl == TYPE_STUB_DECL (TREE_TYPE (decl))) \
+          /* This is necessary for stub decls that     \
+             appear in nested inline functions.  */    \
+          || (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE \
+              && (decl_ultimate_origin (decl)          \
+                  == TYPE_STUB_DECL (TREE_TYPE (decl)))))))
 
 /* Information concerning the compilation unit's programming
    language, and compiler version.  */
@@ -1705,8 +1726,8 @@ static unsigned long next_die_offset;
 /* Record the root of the DIE's built for the current compilation unit.  */
 static dw_die_ref comp_unit_die;
 
-/* The number of DIEs with a NULL parent waiting to be relocated.  */
-static int limbo_die_count;
+/* A list of DIEs with a NULL parent waiting to be relocated.  */
+static limbo_die_node *limbo_die_list = 0;
 
 /* Pointer to an array of filenames referenced by this compilation unit.  */
 static char **file_table;
@@ -1977,7 +1998,8 @@ static tree field_type                    PROTO((tree));
 static unsigned simple_type_align_in_bits PROTO((tree));
 static unsigned simple_type_size_in_bits PROTO((tree));
 static unsigned field_byte_offset              PROTO((tree));
-static void add_location_attribute     PROTO((dw_die_ref, rtx));
+static void add_AT_location_description        PROTO((dw_die_ref,
+                                              enum dwarf_attribute, rtx));
 static void add_data_member_location_attribute PROTO((dw_die_ref, tree));
 static void add_const_value_attribute  PROTO((dw_die_ref, rtx));
 static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
@@ -3608,7 +3630,14 @@ new_die (tag_value, parent_die)
   if (parent_die != NULL)
     add_child_die (parent_die, die);
   else
-    ++limbo_die_count;
+    {
+      limbo_die_node *limbo_node;
+
+      limbo_node = (limbo_die_node *) xmalloc (sizeof (limbo_die_node));
+      limbo_node->die = die;
+      limbo_node->next = limbo_die_list;
+      limbo_die_list = limbo_node;
+    }
 
   return die;
 }
@@ -6097,14 +6126,16 @@ field_byte_offset (decl)
 /* The following routines define various Dwarf attributes and any data
    associated with them.  */
 
+/* Add a location description attribute value to a DIE.
 
-/* Output the form of location attributes suitable for whole variables and
+   This emits location attributes suitable for whole variables and
    whole parameters.  Note that the location attributes for struct fields are
    generated by the routine `data_member_location_attribute' below.  */
 
 static void
-add_location_attribute (die, rtl)
+add_AT_location_description (die, attr_kind, rtl)
      dw_die_ref die;
+     enum dwarf_attribute attr_kind;
      register rtx rtl;
 {
   dw_loc_descr_ref loc_descr = NULL;
@@ -6138,7 +6169,7 @@ add_location_attribute (die, rtl)
     loc_descr = loc_descriptor (gen_rtx (REG, word_mode, 0));
 #endif
 
-  add_AT_loc (die, DW_AT_location, loc_descr);
+  add_AT_loc (die, attr_kind, loc_descr);
 }
 
 /* Attach the specialized form of location attribute used for data
@@ -6429,7 +6460,7 @@ add_location_or_const_value_attribute (die, decl)
     case MEM:
     case REG:
     case SUBREG:
-      add_location_attribute (die, rtl);
+      add_AT_location_description (die, DW_AT_location, rtl);
       break;
 
     default:
@@ -6459,6 +6490,13 @@ add_bound_info (subrange_die, bound_attr, bound)
      register tree bound;
 {
   register unsigned bound_value = 0;
+
+  /* If this is an Ada unconstrained array type, then don't emit any debug
+     info because the array bounds are unknown.  They are parameterized when
+     the type is instantiated.  */
+  if (contains_placeholder_p (bound))
+    return;
+
   switch (TREE_CODE (bound))
     {
     case ERROR_MARK:
@@ -6510,13 +6548,20 @@ add_bound_info (subrange_die, bound_attr, bound)
          register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
          add_AT_flag (decl_die, DW_AT_artificial, 1);
          add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
-         add_location_attribute (decl_die, SAVE_EXPR_RTL (bound));
+         add_AT_location_description (decl_die, DW_AT_location,
+                                      SAVE_EXPR_RTL (bound));
          add_AT_die_ref (subrange_die, bound_attr, decl_die);
        }
 
       /* Else leave out the attribute.  */
       break;
 
+    case MAX_EXPR:
+    case VAR_DECL:
+      /* ??? These types of bounds can be created by the Ada front end,
+        and it isn't clear how to emit debug info for them.  */
+      break;
+
     default:
       abort ();
     }
@@ -6567,8 +6612,19 @@ add_subscript_info (type_die, type)
 
          /* define the index type.  */
          if (TREE_TYPE (domain))
-           add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
-                               type_die);
+           {
+             /* ??? This is probably an Ada unnamed subrange type.  Ignore the
+                TREE_TYPE field.  We can't emit debug info for this
+                because it is an unnamed integral type.  */
+             if (TREE_CODE (domain) == INTEGER_TYPE
+                 && TYPE_NAME (domain) == NULL_TREE
+                 && TREE_CODE (TREE_TYPE (domain)) == INTEGER_TYPE
+                 && TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE)
+               ;       
+             else
+               add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
+                                   type_die);
+           }
 
          add_bound_info (subrange_die, DW_AT_lower_bound, lower);
          add_bound_info (subrange_die, DW_AT_upper_bound, upper);
@@ -6818,12 +6874,6 @@ scope_die_for (t, context_die)
   register tree containing_scope;
   register unsigned long i;
 
-  /* Function-local tags and functions get stuck in limbo until they are
-     fixed up by decls_for_scope.  */
-  if (context_die == NULL
-      && (TREE_CODE (t) == FUNCTION_DECL || is_tagged_type (t)))
-    return NULL;
-
   /* Walk back up the declaration tree looking for a place to define
      this type.  */
   if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
@@ -6833,6 +6883,12 @@ scope_die_for (t, context_die)
   else
     containing_scope = DECL_CONTEXT (t);
 
+  /* Function-local tags and functions get stuck in limbo until they are
+     fixed up by decls_for_scope.  */
+  if (context_die == NULL && containing_scope != NULL_TREE
+      && (TREE_CODE (t) == FUNCTION_DECL || is_tagged_type (t)))
+    return NULL;
+
   if (containing_scope == NULL_TREE)
     scope_die = comp_unit_die;
   else
@@ -6877,8 +6933,10 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
   register enum tree_code code  = TREE_CODE (type);
   register dw_die_ref type_die  = NULL;
 
-  /* If this type is an unnamed subtype of an integral or floating-point
-     type, use the inner type.  */
+  /* ??? If this type is an unnamed subrange type of an integral or
+     floating-point type, use the inner type.  This is because we have no
+     support for unnamed types in base_type_die.  This can happen if this is
+     an Ada subrange type.  Correct solution is emit a subrange type die.  */
   if ((code == INTEGER_TYPE || code == REAL_TYPE)
       && TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0)
     type = TREE_TYPE (type), code = TREE_CODE (type);
@@ -7177,6 +7235,11 @@ gen_enumeration_type_die (type, context_die)
       if (type_tag (type))
        add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
 
+      /* If the first reference to this type was as the return type of an
+        inline function, then it may not have a parent.  Fix this now.  */
+      if (type_die->die_parent == NULL)
+       add_child_die (scope_die_for (type, context_die), type_die);
+
       for (link = TYPE_FIELDS (type);
           link != NULL; link = TREE_CHAIN (link))
        {
@@ -7486,9 +7549,13 @@ gen_subprogram_die (decl, context_die)
        = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
       add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
 
+#if 0
+      /* ??? This fails for nested inline functions, because context_display
+        is not part of the state saved/restored for inline functions.  */
       if (current_function_needs_context)
-       add_AT_loc (subr_die, DW_AT_static_link,
-                   loc_descriptor (lookup_static_chain (decl)));
+       add_AT_location_description (subr_die, DW_AT_static_link,
+                                    lookup_static_chain (decl));
+#endif
     }
 
   /* Now output descriptions of the arguments for this function. This gets
@@ -8028,6 +8095,11 @@ gen_struct_or_union_type_die (type, context_die)
       if (type_tag (type))
        add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
 
+      /* If the first reference to this type was as the return type of an
+        inline function, then it may not have a parent.  Fix this now.  */
+      if (type_die->die_parent == NULL)
+       add_child_die (scope_die, type_die);
+
       push_decl_scope (type);
       gen_member_die (type, type_die);
       pop_decl_scope ();
@@ -8397,10 +8469,7 @@ decls_for_scope (stmt, context_die, depth)
        die = NULL;
 
       if (die != NULL && die->die_parent == NULL)
-       {
-         add_child_die (context_die, die);
-         --limbo_die_count;
-       }
+       add_child_die (context_die, die);
       else
        gen_decl_die (decl, context_die);
     }
@@ -8503,7 +8572,7 @@ gen_decl_die (decl, context_die)
          having been instantiated from some other (original) TYPE_DECL node
          (e.g. one which was generated within the original definition of an
          inline function) we have to generate a special (abbreviated)
-         DW_TAG_structure_type, DW_TAG_union_type, or DW_TAG_enumeration-type 
+         DW_TAG_structure_type, DW_TAG_union_type, or DW_TAG_enumeration_type 
          DIE here.  */
       if (TYPE_DECL_IS_STUB (decl) && DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE)
        {
@@ -8968,6 +9037,33 @@ dwarf2out_init (asm_out_file, main_input_filename)
 void
 dwarf2out_finish ()
 {
+  limbo_die_node *node, *next_node;
+  dw_die_ref die;
+  dw_attr_ref a;
+
+  /* Traverse the limbo die list, and add parent/child links.  The only
+     dies without parents that should be here are concrete instances of
+     inline functions, and the comp_unit_die.  We can ignore the comp_unit_die.
+     For concrete instances, we can get the parent die from the abstract
+     instance.  */
+  for (node = limbo_die_list; node; node = next_node)
+    {
+      next_node = node->next;
+      die = node->die;
+
+      if (die->die_parent == NULL)
+       {
+         a = get_AT (die, DW_AT_abstract_origin);
+         if (a)
+           add_child_die (a->dw_attr_val.v.val_die_ref->die_parent, die);
+         else if (die == comp_unit_die)
+             ;
+         else
+           abort ();
+       }
+      free (node);
+    }
+
   /* Traverse the DIE tree and add sibling attributes to those DIE's
      that have children.  */
   add_sibling_attributes (comp_unit_die);
@@ -9042,8 +9138,5 @@ dwarf2out_finish ()
       ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION);
       output_aranges ();
     }
-
-  /* The only DIE we should have with a parent of NULL is comp_unit_die.  */
-  assert (limbo_die_count == 1);
 }
 #endif /* DWARF2_DEBUGGING_INFO */