OSDN Git Service

* expr.c (expand_expr) [MULT_EXPR]: Do not apply distributive law
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 3c11484..8d7d48b 100644 (file)
@@ -298,11 +298,6 @@ static struct dw_loc_descr_struct *build_cfa_loc
 static void def_cfa_1                  PARAMS ((const char *,
                                                 dw_cfa_location *));
 
-/* .debug_str support.  */
-static hashnode indirect_string_alloc  PARAMS ((hash_table *));
-static int output_indirect_string      PARAMS ((struct cpp_reader *,
-                                                hashnode, const PTR));
-
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
 #define ASM_COMMENT_START ";#"
@@ -478,8 +473,18 @@ dwarf_cfi_name (cfi_opc)
       return "DW_CFA_def_cfa_register";
     case DW_CFA_def_cfa_offset:
       return "DW_CFA_def_cfa_offset";
+
+    /* DWARF 3 */
     case DW_CFA_def_cfa_expression:
       return "DW_CFA_def_cfa_expression";
+    case DW_CFA_expression:
+      return "DW_CFA_expression";
+    case DW_CFA_offset_extended_sf:
+      return "DW_CFA_offset_extended_sf";
+    case DW_CFA_def_cfa_sf:
+      return "DW_CFA_def_cfa_sf";
+    case DW_CFA_def_cfa_offset_sf:
+      return "DW_CFA_def_cfa_offset_sf";
 
     /* SGI/MIPS specific */
     case DW_CFA_MIPS_advance_loc8:
@@ -773,10 +778,7 @@ reg_save (label, reg, sreg, offset)
 #endif
       offset /= DWARF_CIE_DATA_ALIGNMENT;
       if (offset < 0)
-       {
-         cfi->dw_cfi_opc = DW_CFA_GNU_negative_offset_extended;
-         offset = -offset;
-       }
+       cfi->dw_cfi_opc = DW_CFA_offset_extended_sf;
 
       cfi->dw_cfi_oprnd2.dw_cfi_offset = offset;
     }
@@ -1719,13 +1721,19 @@ output_cfi (cfi, fde, for_eh)
          break;
 
        case DW_CFA_offset_extended:
-       case DW_CFA_GNU_negative_offset_extended:
        case DW_CFA_def_cfa:
          dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
                                       NULL);
          dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
          break;
 
+       case DW_CFA_offset_extended_sf:
+       case DW_CFA_def_cfa_sf:
+         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
+                                      NULL);
+         dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
+         break;
+
        case DW_CFA_restore_extended:
        case DW_CFA_undefined:
        case DW_CFA_same_value:
@@ -1746,13 +1754,22 @@ output_cfi (cfi, fde, for_eh)
          dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL);
          break;
 
+       case DW_CFA_def_cfa_offset_sf:
+         dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL);
+         break;
+
        case DW_CFA_GNU_window_save:
          break;
 
        case DW_CFA_def_cfa_expression:
+       case DW_CFA_expression:
          output_cfa_loc (cfi);
          break;
 
+       case DW_CFA_GNU_negative_offset_extended:
+         /* Obsoleted by DW_CFA_offset_extended_sf.  */
+         abort ();
+
        default:
          break;
        }
@@ -2111,7 +2128,7 @@ dwarf2out_end_epilogue ()
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   /* Output a label to mark the endpoint of the code generated for this
-     function.        */
+     function.  */
   ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL, current_funcdef_number);
   ASM_OUTPUT_LABEL (asm_out_file, label);
   fde = &fde_table[fde_table_in_use - 1];
@@ -3046,6 +3063,12 @@ get_cfa_from_loc_descr (cfa, loc)
 /* And now, the support for symbolic debugging information.  */
 #ifdef DWARF2_DEBUGGING_INFO
 
+/* .debug_str support.  */
+static hashnode indirect_string_alloc  PARAMS ((hash_table *));
+static int output_indirect_string      PARAMS ((struct cpp_reader *,
+                                                 hashnode, const PTR));
+
+
 static void dwarf2out_init             PARAMS ((const char *));
 static void dwarf2out_finish           PARAMS ((const char *));
 static void dwarf2out_define           PARAMS ((unsigned int, const char *));
@@ -3242,16 +3265,6 @@ extern int flag_traditional;
 #endif
 #endif
 
-/* Define the architecture-dependent minimum instruction length (in bytes).
-   In this implementation of DWARF, this field is used for information
-   purposes only.  Since GCC generates assembly language, we have
-   no a priori knowledge of how many instruction bytes are generated
-   for each source line, and therefore can use only the  DW_LNE_set_address
-   and DW_LNS_fixed_advance_pc line information commands.  */
-#ifndef DWARF_LINE_MIN_INSTR_LENGTH
-#define DWARF_LINE_MIN_INSTR_LENGTH 4
-#endif
-
 /* Minimum line offset in a special line info. opcode.
    This value was chosen to give a reasonable range of values.  */
 #define DWARF_LINE_BASE  -10
@@ -5115,8 +5128,8 @@ equate_decl_number_to_die (decl, decl_die)
      tree decl;
      dw_die_ref decl_die;
 {
-  unsigned decl_id = DECL_UID (decl);
-  unsigned num_allocated;
+  unsigned int decl_id = DECL_UID (decl);
+  unsigned int num_allocated;
 
   if (decl_id >= decl_die_table_allocated)
     {
@@ -7008,8 +7021,17 @@ output_line_info ()
   dw2_asm_output_delta (DWARF_OFFSET_SIZE, p2, p1, "Prolog Length");
   ASM_OUTPUT_LABEL (asm_out_file, p1);
 
-  dw2_asm_output_data (1, DWARF_LINE_MIN_INSTR_LENGTH,
+  /* Define the architecture-dependent minimum instruction length (in
+   bytes).  In this implementation of DWARF, this field is used for
+   information purposes only.  Since GCC generates assembly language,
+   we have no a priori knowledge of how many instruction bytes are
+   generated for each source line, and therefore can use only the
+   DW_LNE_set_address and DW_LNS_fixed_advance_pc line information
+   commands.  Accordingly, we fix this as `1', which is "correct
+   enough" for all architectures, and don't let the target override.  */
+  dw2_asm_output_data (1, 1,
                       "Minimum Instruction Length");
+
   dw2_asm_output_data (1, DWARF_LINE_DEFAULT_IS_STMT_START,
                       "Default is_stmt_start flag");
   dw2_asm_output_data (1, DWARF_LINE_BASE,
@@ -7778,10 +7800,24 @@ mem_loc_descriptor (rtl, mode)
         by a different symbol.  */
       if (GET_CODE (rtl) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (rtl))
        {
-         rtx tmp = get_pool_constant (rtl);
+         bool marked;
+         rtx tmp = get_pool_constant_mark (rtl, &marked);
 
          if (GET_CODE (tmp) == SYMBOL_REF)
-           rtl = tmp;
+           {
+             rtl = tmp;
+             if (CONSTANT_POOL_ADDRESS_P (tmp))
+               get_pool_constant_mark (tmp, &marked);
+             else
+               marked = true;
+           }
+
+         /* If all references to this pool constant were optimized away,
+            it was not output and thus we can't represent it.
+            FIXME: might try to use DW_OP_const_value here, though
+            DW_OP_piece complicates it.  */
+         if (!marked)
+           return 0;
        }
 
       mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
@@ -7853,6 +7889,14 @@ mem_loc_descriptor (rtl, mode)
       mem_loc_result = int_loc_descriptor (INTVAL (rtl));
       break;
 
+    case ADDRESSOF:
+      /* If this is a MEM, return its address.  Otherwise, we can't
+        represent this.  */
+      if (GET_CODE (XEXP (rtl, 0)) == MEM)
+       return mem_loc_descriptor (XEXP (XEXP (rtl, 0), 0), mode);
+      else
+       return 0;
+
     default:
       abort ();
     }
@@ -7964,6 +8008,24 @@ loc_descriptor_from_tree (loc, addressp)
         the names of types.  */
       return 0;
 
+    case CALL_EXPR:
+      return 0;
+
+    case ADDR_EXPR:
+      /* We can support this only if we can look through conversions and
+        find an INDIRECT_EXPR.  */
+      for (loc = TREE_OPERAND (loc, 0);
+          TREE_CODE (loc) == CONVERT_EXPR || TREE_CODE (loc) == NOP_EXPR
+          || TREE_CODE (loc) == NON_LVALUE_EXPR
+          || TREE_CODE (loc) == VIEW_CONVERT_EXPR
+          || TREE_CODE (loc) == SAVE_EXPR;
+          loc = TREE_OPERAND (loc, 0))
+       ;
+
+       return (TREE_CODE (loc) == INDIRECT_REF
+              ? loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp)
+              : 0);
+
     case VAR_DECL:
     case PARM_DECL:
       {
@@ -8057,14 +8119,19 @@ loc_descriptor_from_tree (loc, addressp)
        return 0;
       break;
 
+    case TRUTH_AND_EXPR: 
+    case TRUTH_ANDIF_EXPR:
     case BIT_AND_EXPR:
       op = DW_OP_and;
       goto do_binop;
 
+    case TRUTH_XOR_EXPR:
     case BIT_XOR_EXPR:
       op = DW_OP_xor;
       goto do_binop;
 
+    case TRUTH_OR_EXPR:
+    case TRUTH_ORIF_EXPR:
     case BIT_IOR_EXPR:
       op = DW_OP_or;
       goto do_binop;
@@ -8158,6 +8225,7 @@ loc_descriptor_from_tree (loc, addressp)
       add_loc_descr (&ret, new_loc_descr (op, 0, 0));
       break;
 
+    case TRUTH_NOT_EXPR:
     case BIT_NOT_EXPR:
       op = DW_OP_not;
       goto do_unop;
@@ -8184,7 +8252,7 @@ loc_descriptor_from_tree (loc, addressp)
                          TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)),
                   TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0));
 
-      /* ... fall through ... */
+      /* ... fall through ...  */
 
     case COND_EXPR:
       {
@@ -8962,7 +9030,7 @@ add_bound_info (subrange_die, bound_attr, bound)
     case ERROR_MARK:
       return;
 
-    /* All fixed-bounds are represented by INTEGER_CST nodes.        */
+    /* All fixed-bounds are represented by INTEGER_CST nodes.  */
     case INTEGER_CST:
       if (! host_integerp (bound, 0)
          || (bound_attr == DW_AT_lower_bound
@@ -9062,6 +9130,15 @@ add_bound_info (subrange_die, bound_attr, bound)
        else
          ctx = lookup_decl_die (current_function_decl);
 
+       /* If we weren't able to find a context, it's most likely the case
+          that we are processing the return type of the function.  So
+          make a SAVE_EXPR to point to it and have the limbo DIE code
+          find the proper die.  The save_expr function doesn't always
+          make a SAVE_EXPR, so do it ourselves.  */
+       if (ctx == 0)
+         bound = build (SAVE_EXPR, TREE_TYPE (bound), bound,
+                        current_function_decl, NULL_TREE);
+
        decl_die = new_die (DW_TAG_variable, ctx, bound);
        add_AT_flag (decl_die, DW_AT_artificial, 1);
        add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
@@ -10820,7 +10897,8 @@ gen_struct_or_union_type_die (type, context_die)
       add_AT_flag (type_die, DW_AT_declaration, 1);
 
       /* We don't need to do this for function-local types.  */
-      if (! decl_function_context (TYPE_STUB_DECL (type)))
+      if (TYPE_STUB_DECL (type)
+         && ! decl_function_context (TYPE_STUB_DECL (type)))
        VARRAY_PUSH_TREE (incomplete_types, type);
     }
 }
@@ -11997,6 +12075,18 @@ dwarf2out_finish (input_filename)
            add_child_die (origin->die_parent, die);
          else if (die == comp_unit_die)
            ;
+         /* If this was an expression for a bound involved in a function
+            return type, it may be a SAVE_EXPR for which we weren't able
+            to find a DIE previously.  So try now.  */
+         else if (node->created_for
+                  && TREE_CODE (node->created_for) == SAVE_EXPR
+                  && 0 != (origin = (lookup_decl_die
+                                     (SAVE_EXPR_CONTEXT
+                                      (node->created_for)))))
+           add_child_die (origin, die);
+         else if (errorcount > 0 || sorrycount > 0)
+           /* It's OK to be confused by errors in the input.  */
+           add_child_die (comp_unit_die, die);
          else if (node->created_for
                   && ((DECL_P (node->created_for)
                        && (context = DECL_CONTEXT (node->created_for)))
@@ -12014,9 +12104,6 @@ dwarf2out_finish (input_filename)
                abort ();
              add_child_die (origin, die);
            }
-         else if (errorcount > 0 || sorrycount > 0)
-           /* It's OK to be confused by errors in the input.  */
-           add_child_die (comp_unit_die, die);
          else
            abort ();
        }