OSDN Git Service

* cse.c (exp_equiv_p): Special case CONST_DOUBLE.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index bbd2b32..970cbb5 100644 (file)
@@ -19,8 +19,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* TODO: Emit .debug_line header even when there are no functions, since
           the file numbers are used by .debug_info.  Alternately, leave
@@ -499,7 +499,8 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
        if (offset < 0)
          continue;
 
-       emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+       emit_move_insn (adjust_address (mem, mode, offset),
+                       gen_int_mode (size, mode));
       }
 
 #ifdef DWARF_ALT_FRAME_RETURN_COLUMN
@@ -2659,7 +2660,6 @@ static const char *dwarf_stack_op_name (unsigned);
 static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
                                       unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
 static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
-static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
 static unsigned long size_of_loc_descr (dw_loc_descr_ref);
 static unsigned long size_of_locs (dw_loc_descr_ref);
 static void output_loc_operands (dw_loc_descr_ref);
@@ -2997,7 +2997,6 @@ new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
   return descr;
 }
 
-
 /* Add a location description term to a location description expression.  */
 
 static inline void
@@ -3012,27 +3011,6 @@ add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
   *d = descr;
 }
 
-
-/* Optionally add a DW_OP_piece term to a location description expression.
-   DW_OP_piece is only added if the location description expression already
-   doesn't end with DW_OP_piece.  */
-
-static void
-add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
-{
-  dw_loc_descr_ref loc;
-
-  if (*list_head != NULL)
-    {
-      /* Find the end of the chain.  */
-      for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
-       ;
-
-      if (loc->dw_loc_opc != DW_OP_piece)
-       loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
-    }
-}
-
 /* Return the size of a location descriptor.  */
 
 static unsigned long
@@ -3470,7 +3448,7 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc)
          cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned;
          break;
        default:
-         internal_error ("DW_LOC_OP %s not implemented\n",
+         internal_error ("DW_LOC_OP %s not implemented",
                          dwarf_stack_op_name (ptr->dw_loc_opc));
        }
     }
@@ -3996,6 +3974,7 @@ static dw_die_ref subrange_type_die (tree, dw_die_ref);
 static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
 static int type_is_enum (tree);
 static unsigned int dbx_reg_number (rtx);
+static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
 static dw_loc_descr_ref reg_loc_descriptor (rtx);
 static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
 static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
@@ -4652,6 +4631,9 @@ dwarf_form_name (unsigned int form)
 static tree
 decl_ultimate_origin (tree decl)
 {
+  if (!CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_COMMON))
+    return NULL_TREE;
+
   /* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
      nodes in the function to point to themselves; ignore that if
      we're trying to output the abstract instance of this function.  */
@@ -8432,6 +8414,26 @@ dbx_reg_number (rtx rtl)
   return DBX_REGISTER_NUMBER (regno);
 }
 
+/* Optionally add a DW_OP_piece term to a location description expression.
+   DW_OP_piece is only added if the location description expression already
+   doesn't end with DW_OP_piece.  */
+
+static void
+add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
+{
+  dw_loc_descr_ref loc;
+
+  if (*list_head != NULL)
+    {
+      /* Find the end of the chain.  */
+      for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
+       ;
+
+      if (loc->dw_loc_opc != DW_OP_piece)
+       loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
+    }
+}
+
 /* Return a location descriptor that designates a machine register or
    zero if there is none.  */
 
@@ -8952,7 +8954,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
       return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 1);
 
     case VAR_DECL:
-      if (DECL_THREAD_LOCAL (loc))
+      if (DECL_THREAD_LOCAL_P (loc))
        {
          rtx rtl;
 
@@ -10144,7 +10146,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
         XXX: If you split a variable across multiple sections, this
         won't notice.  */
 
-      if (DECL_SECTION_NAME (decl))
+      if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_SECTION_NAME (decl))
        {
          tree sectree = DECL_SECTION_NAME (decl);
          secname = TREE_STRING_POINTER (sectree);
@@ -11624,6 +11626,25 @@ gen_variable_die (tree decl, dw_die_ref context_die)
 
   dw_die_ref old_die = lookup_decl_die (decl);
   int declaration = (DECL_EXTERNAL (decl)
+                    /* If DECL is COMDAT and has not actually been
+                       emitted, we cannot take its address; there
+                       might end up being no definition anywhere in
+                       the program.  For example, consider the C++
+                       test case:
+
+                          template <class T>
+                          struct S { static const int i = 7; };
+
+                          template <class T>
+                          const int S<T>::i;
+
+                          int f() { return S<int>::i; }
+                         
+                       Here, S<int>::i is not DECL_EXTERNAL, but no
+                       definition is required, so the compiler will
+                       not emit a definition.  */  
+                    || (TREE_CODE (decl) == VAR_DECL
+                        && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
                     || class_or_namespace_scope_p (context_die));
 
   if (origin != NULL)
@@ -11736,6 +11757,20 @@ gen_label_die (tree decl, dw_die_ref context_die)
     }
 }
 
+/* A helper function for gen_inlined_subroutine_die.  Add source coordinate
+   attributes to the DIE for a block STMT, to describe where the inlined
+   function was called from.  This is similar to add_src_coords_attributes.  */
+
+static inline void
+add_call_src_coords_attributes (tree stmt, dw_die_ref die)
+{
+  expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt));
+  unsigned file_index = lookup_filename (s.file);
+
+  add_AT_unsigned (die, DW_AT_call_file, file_index);
+  add_AT_unsigned (die, DW_AT_call_line, s.line);
+}
+
 /* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
    Add low_pc and high_pc attributes to the DIE for a block STMT.  */
 
@@ -11803,6 +11838,7 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
 
       add_abstract_origin_attribute (subr_die, decl);
       add_high_low_attributes (stmt, subr_die);
+      add_call_src_coords_attributes (stmt, subr_die);
 
       decls_for_scope (stmt, subr_die, depth);
       current_function_has_inlines = 1;
@@ -12525,6 +12561,11 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
          
          if (die != NULL && die->die_parent == NULL)
            add_child_die (context_die, die);
+         /* Do not produce debug information for static variables since
+            these might be optimized out.  We are called for these later
+            in cgraph_varpool_analyze_pending_decls. */
+         if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+           ;
          else
            gen_decl_die (decl, context_die);
        }
@@ -13072,6 +13113,10 @@ dwarf2out_decl (tree decl)
       if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
        return;
 
+      /* For local statics lookup proper context die.  */
+      if (TREE_STATIC (decl) && decl_function_context (decl))
+       context_die = lookup_decl_die (DECL_CONTEXT (decl));
+
       /* If we are in terse mode, don't generate any DIEs to represent any
         variable declarations or definitions.  */
       if (debug_info_level <= DINFO_LEVEL_TERSE)
@@ -13217,6 +13262,12 @@ lookup_filename (const char *file_name)
   return i;
 }
 
+/* If the assembler will construct the file table, then translate the compiler
+   internal file table number into the assembler file table number, and emit
+   a .file directive if we haven't already emitted one yet.  The file table
+   numbers are different because we prune debug info for unused variables and
+   types, which may include filenames.  */
+
 static int
 maybe_emit_file (int fileno)
 {
@@ -13237,6 +13288,8 @@ maybe_emit_file (int fileno)
     return fileno;
 }
 
+/* Initialize the compiler internal file table.  */
+
 static void
 init_file_table (void)
 {
@@ -13614,7 +13667,7 @@ prune_unused_types_walk_attribs (dw_die_ref die)
             Make sure that it will get emitted.  */
          prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
        }
-      else if (a->dw_attr == DW_AT_decl_file)
+      else if (a->dw_attr == DW_AT_decl_file || a->dw_attr == DW_AT_call_file)
        {
          /* A reference to a file.  Make sure the file name is emitted.  */
          a->dw_attr_val.v.val_unsigned =