gdb/ChangeLog: Fix filenames in a couple of entries
[deliverable/binutils-gdb.git] / gdb / ada-lang.c
index 8a0423eb5d0b71c8a3f6d6de99ae17e1a9cf462f..11939d77986b4ba035e028cad4351011535d07f8 100644 (file)
@@ -1,6 +1,6 @@
 /* Ada language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   Copyright (C) 1992-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -48,7 +48,7 @@
 #include "annotate.h"
 #include "valprint.h"
 #include "source.h"
-#include "observer.h"
+#include "observable.h"
 #include "vec.h"
 #include "stack.h"
 #include "gdb_vecs.h"
@@ -124,10 +124,10 @@ static int num_defns_collected (struct obstack *);
 
 static struct block_symbol *defns_collected (struct obstack *, int);
 
-static struct value *resolve_subexp (struct expression **, int *, int,
+static struct value *resolve_subexp (expression_up *, int *, int,
                                      struct type *);
 
-static void replace_operator_with_call (struct expression **, int, int, int,
+static void replace_operator_with_call (expression_up *, int, int, int,
                                         struct symbol *, const struct block *);
 
 static int possible_user_operator_p (enum exp_opcode, struct value **);
@@ -225,9 +225,6 @@ static struct value *ada_value_primitive_field (struct value *, int, int,
 static int find_struct_field (const char *, struct type *, int,
                               struct type **, int *, int *, int *, int *);
 
-static struct value *ada_to_fixed_value_create (struct type *, CORE_ADDR,
-                                                struct value *);
-
 static int ada_resolve_function (struct block_symbol *, int,
                                  struct value **, int, const char *,
                                  struct type *);
@@ -916,7 +913,7 @@ char *
 ada_main_name (void)
 {
   struct bound_minimal_symbol msym;
-  static char *main_program_name = NULL;
+  static gdb::unique_xmalloc_ptr<char> main_program_name;
 
   /* For Ada, the name of the main procedure is stored in a specific
      string constant, generated by the binder.  Look for that symbol,
@@ -934,13 +931,12 @@ ada_main_name (void)
       if (main_program_name_addr == 0)
         error (_("Invalid address for Ada main program name."));
 
-      xfree (main_program_name);
       target_read_string (main_program_name_addr, &main_program_name,
                           1024, &err_code);
 
       if (err_code != 0)
         return NULL;
-      return main_program_name;
+      return main_program_name.get ();
     }
 
   /* The main procedure doesn't seem to be in Ada.  */
@@ -2910,8 +2906,10 @@ ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
   struct type *base_index_type = TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type0));
   struct type *index_type
     = create_static_range_type (NULL, base_index_type, low, high);
-  struct type *slice_type =
-    create_array_type (NULL, TYPE_TARGET_TYPE (type0), index_type);
+  struct type *slice_type = create_array_type_with_stride
+                             (NULL, TYPE_TARGET_TYPE (type0), index_type,
+                              get_dyn_prop (DYN_PROP_BYTE_STRIDE, type0),
+                              TYPE_FIELD_BITSIZE (type0, 0));
   int base_low =  ada_discrete_type_low_bound (TYPE_INDEX_TYPE (type0));
   LONGEST base_low_pos, low_pos;
   CORE_ADDR base;
@@ -2938,8 +2936,10 @@ ada_value_slice (struct value *array, int low, int high)
   struct type *base_index_type = TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type));
   struct type *index_type
     = create_static_range_type (NULL, TYPE_INDEX_TYPE (type), low, high);
-  struct type *slice_type =
-    create_array_type (NULL, TYPE_TARGET_TYPE (type), index_type);
+  struct type *slice_type = create_array_type_with_stride
+                             (NULL, TYPE_TARGET_TYPE (type), index_type,
+                              get_dyn_prop (DYN_PROP_BYTE_STRIDE, type),
+                              TYPE_FIELD_BITSIZE (type, 0));
   LONGEST low_pos, high_pos;
 
   if (!discrete_position (base_index_type, low, &low_pos)
@@ -3175,7 +3175,7 @@ ada_array_length (struct value *arr, int n)
     }
 
   arr_type = check_typedef (arr_type);
-  index_type = TYPE_INDEX_TYPE (arr_type);
+  index_type = ada_index_type (arr_type, n, "length");
   if (index_type != NULL)
     {
       struct type *base_type;
@@ -3235,7 +3235,7 @@ ada_decoded_op_name (enum exp_opcode op)
    return type is preferred.  May change (expand) *EXP.  */
 
 static void
-resolve (struct expression **expp, int void_context_p)
+resolve (expression_up *expp, int void_context_p)
 {
   struct type *context_type = NULL;
   int pc = 0;
@@ -3256,7 +3256,7 @@ resolve (struct expression **expp, int void_context_p)
    are as in ada_resolve, above.  */
 
 static struct value *
-resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
+resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
                 struct type *context_type)
 {
   int pc = *pos;
@@ -3270,7 +3270,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
 
   argvec = NULL;
   nargs = 0;
-  exp = *expp;
+  exp = expp->get ();
 
   /* Pass one: resolve operands, saving their types and updating *pos,
      if needed.  */
@@ -3420,7 +3420,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
   for (i = 0; i < nargs; i += 1)
     argvec[i] = resolve_subexp (expp, pos, 1, NULL);
   argvec[i] = NULL;
-  exp = *expp;
+  exp = expp->get ();
 
   /* Pass two: perform any resolution on principal operator.  */
   switch (op)
@@ -3503,9 +3503,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
 
           exp->elts[pc + 1].block = candidates[i].block;
           exp->elts[pc + 2].symbol = candidates[i].symbol;
-          if (innermost_block == NULL
-              || contained_in (candidates[i].block, innermost_block))
-            innermost_block = candidates[i].block;
+         innermost_block.update (candidates[i]);
         }
 
       if (deprocedure_p
@@ -3515,7 +3513,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
           replace_operator_with_call (expp, pc, 0, 0,
                                       exp->elts[pc + 2].symbol,
                                       exp->elts[pc + 1].block);
-          exp = *expp;
+          exp = expp->get ();
         }
       break;
 
@@ -3550,9 +3548,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
 
             exp->elts[pc + 4].block = candidates[i].block;
             exp->elts[pc + 5].symbol = candidates[i].symbol;
-            if (innermost_block == NULL
-                || contained_in (candidates[i].block, innermost_block))
-              innermost_block = candidates[i].block;
+           innermost_block.update (candidates[i]);
           }
       }
       break;
@@ -3596,7 +3592,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
          replace_operator_with_call (expp, pc, nargs, 1,
                                      candidates[i].symbol,
                                      candidates[i].block);
-          exp = *expp;
+          exp = expp->get ();
         }
       break;
 
@@ -4115,7 +4111,7 @@ get_selections (int *choices, int n_choices, int max_results,
    arguments.  Update *EXPP as needed to hold more space.  */
 
 static void
-replace_operator_with_call (struct expression **expp, int pc, int nargs,
+replace_operator_with_call (expression_up *expp, int pc, int nargs,
                             int oplen, struct symbol *sym,
                             const struct block *block)
 {
@@ -4124,7 +4120,7 @@ replace_operator_with_call (struct expression **expp, int pc, int nargs,
   struct expression *newexp = (struct expression *)
     xzalloc (sizeof (struct expression)
              + EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen));
-  struct expression *exp = *expp;
+  struct expression *exp = expp->get ();
 
   newexp->nelts = exp->nelts + 7 - oplen;
   newexp->language_defn = exp->language_defn;
@@ -4140,8 +4136,7 @@ replace_operator_with_call (struct expression **expp, int pc, int nargs,
   newexp->elts[pc + 4].block = block;
   newexp->elts[pc + 5].symbol = sym;
 
-  *expp = newexp;
-  xfree (exp);
+  expp->reset (newexp);
 }
 
 /* Type-class predicates */
@@ -4767,7 +4762,7 @@ cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
    searching for all symbols matching LOOKUP_NAME.
 
    LOOKUP_NAME is expected to be a symbol name after transformation
-   for Ada lookups (see ada_name_for_lookup).  */
+   for Ada lookups.  */
 
 static symbol_name_match_type
 name_match_type_from_name (const char *lookup_name)
@@ -5908,10 +5903,6 @@ ada_lookup_encoded_symbol (const char *name, const struct block *block,
                           domain_enum domain,
                           struct block_symbol *info)
 {
-  struct block_symbol *candidates;
-  int n_candidates;
-  struct cleanup *old_chain;
-
   /* Since we already have an encoded name, wrap it in '<>' to force a
      verbatim match.  Otherwise, if the name happens to not look like
      an encoded name (because it doesn't include a "__"),
@@ -5921,22 +5912,7 @@ ada_lookup_encoded_symbol (const char *name, const struct block *block,
   std::string verbatim = std::string ("<") + name + '>';
 
   gdb_assert (info != NULL);
-  memset (info, 0, sizeof (struct block_symbol));
-
-  n_candidates = ada_lookup_symbol_list (verbatim.c_str (), block,
-                                        domain, &candidates);
-  old_chain = make_cleanup (xfree, candidates);
-
-  if (n_candidates == 0)
-    {
-      do_cleanups (old_chain);
-      return;
-    }
-
-  *info = candidates[0];
-  info->symbol = fixup_symbol_section (info->symbol, NULL);
-
-  do_cleanups (old_chain);
+  *info = ada_lookup_symbol (verbatim.c_str (), block, domain, NULL);
 }
 
 /* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing
@@ -5949,13 +5925,27 @@ struct block_symbol
 ada_lookup_symbol (const char *name, const struct block *block0,
                    domain_enum domain, int *is_a_field_of_this)
 {
-  struct block_symbol info;
-
   if (is_a_field_of_this != NULL)
     *is_a_field_of_this = 0;
 
-  ada_lookup_encoded_symbol (ada_encode (ada_fold_name (name)),
-                            block0, domain, &info);
+  struct block_symbol *candidates;
+  int n_candidates;
+  struct cleanup *old_chain;
+
+  n_candidates = ada_lookup_symbol_list (name, block0, domain, &candidates);
+  old_chain = make_cleanup (xfree, candidates);
+
+  if (n_candidates == 0)
+    {
+      do_cleanups (old_chain);
+      return {};
+    }
+
+  block_symbol info = candidates[0];
+  info.symbol = fixup_symbol_section (info.symbol, NULL);
+
+  do_cleanups (old_chain);
+
   return info;
 }
 
@@ -6501,8 +6491,25 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
     if (completion_skip_symbol (mode, msymbol))
       continue;
 
+    language symbol_language = MSYMBOL_LANGUAGE (msymbol);
+
+    /* Ada minimal symbols won't have their language set to Ada.  If
+       we let completion_list_add_name compare using the
+       default/C-like matcher, then when completing e.g., symbols in a
+       package named "pck", we'd match internal Ada symbols like
+       "pckS", which are invalid in an Ada expression, unless you wrap
+       them in '<' '>' to request a verbatim match.
+
+       Unfortunately, some Ada encoded names successfully demangle as
+       C++ symbols (using an old mangling scheme), such as "name__2Xn"
+       -> "Xn::name(void)" and thus some Ada minimal symbols end up
+       with the wrong language set.  Paper over that issue here.  */
+    if (symbol_language == language_auto
+       || symbol_language == language_cplus)
+      symbol_language = language_ada;
+
     completion_list_add_name (tracker,
-                             MSYMBOL_LANGUAGE (msymbol),
+                             symbol_language,
                              MSYMBOL_LINKAGE_NAME (msymbol),
                              lookup_name, text, word);
   }
@@ -9101,11 +9108,28 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
             const char *name = ada_type_name (fixed_record_type);
             char *xvz_name
              = (char *) alloca (strlen (name) + 7 /* "___XVZ\0" */);
+           bool xvz_found = false;
             LONGEST size;
 
             xsnprintf (xvz_name, strlen (name) + 7, "%s___XVZ", name);
-            if (get_int_var_value (xvz_name, size)
-               && TYPE_LENGTH (fixed_record_type) != size)
+           TRY
+             {
+               xvz_found = get_int_var_value (xvz_name, size);
+             }
+           CATCH (except, RETURN_MASK_ERROR)
+             {
+               /* We found the variable, but somehow failed to read
+                  its value.  Rethrow the same error, but with a little
+                  bit more information, to help the user understand
+                  what went wrong (Eg: the variable might have been
+                  optimized out).  */
+               throw_error (except.error,
+                            _("unable to read value of %s (%s)"),
+                            xvz_name, except.message);
+             }
+           END_CATCH
+
+            if (xvz_found && TYPE_LENGTH (fixed_record_type) != size)
               {
                 fixed_record_type = copy_type (fixed_record_type);
                 TYPE_LENGTH (fixed_record_type) = size;
@@ -9324,8 +9348,16 @@ ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
 
   if (type == type0 && val0 != NULL)
     return val0;
-  else
-    return value_from_contents_and_address (type, 0, address);
+
+  if (VALUE_LVAL (val0) != lval_memory)
+    {
+      /* Our value does not live in memory; it could be a convenience
+        variable, for instance.  Create a not_lval value using val0's
+        contents.  */
+      return value_from_contents (type, value_contents (val0));
+    }
+
+  return value_from_contents_and_address (type, 0, address);
 }
 
 /* A value representing VAL, but with a standard (static-sized) type
@@ -9960,8 +9992,9 @@ assign_component (struct value *container, struct value *lhs, LONGEST index,
 {
   struct value *mark = value_mark ();
   struct value *elt;
+  struct type *lhs_type = check_typedef (value_type (lhs));
 
-  if (TYPE_CODE (value_type (lhs)) == TYPE_CODE_ARRAY)
+  if (TYPE_CODE (lhs_type) == TYPE_CODE_ARRAY)
     {
       struct type *index_type = builtin_type (exp->gdbarch)->builtin_int;
       struct value *index_val = value_from_longest (index_type, index);
@@ -10020,11 +10053,11 @@ assign_aggregate (struct value *container,
   if (!deprecated_value_modifiable (lhs))
     error (_("Left operand of assignment is not a modifiable lvalue."));
 
-  lhs_type = value_type (lhs);
+  lhs_type = check_typedef (value_type (lhs));
   if (ada_is_direct_array_type (lhs_type))
     {
       lhs = ada_coerce_to_simple_array (lhs);
-      lhs_type = value_type (lhs);
+      lhs_type = check_typedef (value_type (lhs));
       low_index = TYPE_ARRAY_LOWER_BOUND_VALUE (lhs_type);
       high_index = TYPE_ARRAY_UPPER_BOUND_VALUE (lhs_type);
     }
@@ -12003,6 +12036,10 @@ struct exception_support_info
       a catchpoint on failed assertions.  */
    const char *catch_assert_sym;
 
+   /* The name of the symbol to break on in order to insert
+      a catchpoint on exception handling.  */
+   const char *catch_handlers_sym;
+
    /* Assuming that the inferior just triggered an unhandled exception
       catchpoint, this function is responsible for returning the address
       in inferior memory where the name of that exception is stored.
@@ -12022,6 +12059,7 @@ static const struct exception_support_info default_exception_support_info =
   "__gnat_debug_raise_exception", /* catch_exception_sym */
   "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
   "__gnat_debug_raise_assert_failure", /* catch_assert_sym */
+  "__gnat_begin_handler", /* catch_handlers_sym */
   ada_unhandled_exception_name_addr
 };
 
@@ -12034,6 +12072,7 @@ static const struct exception_support_info exception_support_info_fallback =
   "__gnat_raise_nodefer_with_msg", /* catch_exception_sym */
   "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
   "system__assertions__raise_assert_failure",  /* catch_assert_sym */
+  "__gnat_begin_handler", /* catch_handlers_sym */
   ada_unhandled_exception_name_addr_from_raise
 };
 
@@ -12302,7 +12341,12 @@ ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex,
       case ada_catch_exception_unhandled:
         return data->exception_info->unhandled_exception_name_addr ();
         break;
-      
+
+      case ada_catch_handlers:
+        return 0;  /* The runtimes does not provide access to the exception
+                     name.  */
+        break;
+
       case ada_catch_assert:
         return 0;  /* Exception name is not relevant in this case.  */
         break;
@@ -12408,7 +12452,9 @@ ada_exception_name_addr (enum ada_exception_catchpoint_kind ex,
   return result;
 }
 
-static char *ada_exception_catchpoint_cond_string (const char *excep_string);
+static char *ada_exception_catchpoint_cond_string
+  (const char *excep_string,
+   enum ada_exception_catchpoint_kind ex);
 
 /* Ada catchpoints.
 
@@ -12471,7 +12517,8 @@ struct ada_catchpoint : public breakpoint
    catchpoint's locations, and store them for later evaluation.  */
 
 static void
-create_excep_cond_exprs (struct ada_catchpoint *c)
+create_excep_cond_exprs (struct ada_catchpoint *c,
+                         enum ada_exception_catchpoint_kind ex)
 {
   struct cleanup *old_chain;
   struct bp_location *bl;
@@ -12487,7 +12534,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
 
   /* Compute the condition expression in text form, from the specific
      expection we want to catch.  */
-  cond_string = ada_exception_catchpoint_cond_string (c->excep_string);
+  cond_string = ada_exception_catchpoint_cond_string (c->excep_string, ex);
   old_chain = make_cleanup (xfree, cond_string);
 
   /* Iterate over all the catchpoint's locations, and parse an
@@ -12555,7 +12602,7 @@ re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
 
   /* Reparse the exception conditional expressions.  One for each
      location.  */
-  create_excep_cond_exprs (c);
+  create_excep_cond_exprs (c, ex);
 }
 
 /* Returns true if we should stop for this breakpoint hit.  If the
@@ -12644,6 +12691,7 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
     {
       case ada_catch_exception:
       case ada_catch_exception_unhandled:
+      case ada_catch_handlers:
        {
          const CORE_ADDR addr = ada_exception_name_addr (ex, b);
          char exception_name[256];
@@ -12741,6 +12789,17 @@ print_one_exception (enum ada_exception_catchpoint_kind ex,
         uiout->field_string ("what", "unhandled Ada exceptions");
         break;
       
+      case ada_catch_handlers:
+        if (c->excep_string != NULL)
+          {
+           uiout->field_fmt ("what",
+                             _("`%s' Ada exception handlers"),
+                             c->excep_string);
+          }
+        else
+         uiout->field_string ("what", "all Ada exceptions handlers");
+        break;
+
       case ada_catch_assert:
         uiout->field_string ("what", "failed Ada assertions");
         break;
@@ -12784,7 +12843,19 @@ print_mention_exception (enum ada_exception_catchpoint_kind ex,
       case ada_catch_exception_unhandled:
         uiout->text (_("unhandled Ada exceptions"));
         break;
-      
+
+      case ada_catch_handlers:
+        if (c->excep_string != NULL)
+         {
+           std::string info
+             = string_printf (_("`%s' Ada exception handlers"),
+                              c->excep_string);
+           uiout->text (info.c_str ());
+         }
+        else
+          uiout->text (_("all Ada exceptions handlers"));
+        break;
+
       case ada_catch_assert:
         uiout->text (_("failed Ada assertions"));
         break;
@@ -12816,6 +12887,10 @@ print_recreate_exception (enum ada_exception_catchpoint_kind ex,
        fprintf_filtered (fp, "catch exception unhandled");
        break;
 
+      case ada_catch_handlers:
+       fprintf_filtered (fp, "catch handlers");
+       break;
+
       case ada_catch_assert:
        fprintf_filtered (fp, "catch assert");
        break;
@@ -12966,6 +13041,54 @@ print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_assert_breakpoint_ops;
 
+/* Virtual table for "catch handlers" breakpoints.  */
+
+static struct bp_location *
+allocate_location_catch_handlers (struct breakpoint *self)
+{
+  return allocate_location_exception (ada_catch_handlers, self);
+}
+
+static void
+re_set_catch_handlers (struct breakpoint *b)
+{
+  re_set_exception (ada_catch_handlers, b);
+}
+
+static void
+check_status_catch_handlers (bpstat bs)
+{
+  check_status_exception (ada_catch_handlers, bs);
+}
+
+static enum print_stop_action
+print_it_catch_handlers (bpstat bs)
+{
+  return print_it_exception (ada_catch_handlers, bs);
+}
+
+static void
+print_one_catch_handlers (struct breakpoint *b,
+                         struct bp_location **last_loc)
+{
+  print_one_exception (ada_catch_handlers, b, last_loc);
+}
+
+static void
+print_mention_catch_handlers (struct breakpoint *b)
+{
+  print_mention_exception (ada_catch_handlers, b);
+}
+
+static void
+print_recreate_catch_handlers (struct breakpoint *b,
+                              struct ui_file *fp)
+{
+  print_recreate_exception (ada_catch_handlers, b, fp);
+}
+
+static struct breakpoint_ops catch_handlers_breakpoint_ops;
+
 /* Return a newly allocated copy of the first space-separated token
    in ARGSP, and then adjust ARGSP to point immediately after that
    token.
@@ -13004,15 +13127,18 @@ ada_get_next_arg (const char **argsp)
    Set EX to the appropriate catchpoint type.
    Set EXCEP_STRING to the name of the specific exception if
    specified by the user.
+   IS_CATCH_HANDLERS_CMD: True if the arguments are for a
+   "catch handlers" command.  False otherwise.
    If a condition is found at the end of the arguments, the condition
    expression is stored in COND_STRING (memory must be deallocated
    after use).  Otherwise COND_STRING is set to NULL.  */
 
 static void
 catch_ada_exception_command_split (const char *args,
+                                  bool is_catch_handlers_cmd,
                                    enum ada_exception_catchpoint_kind *ex,
                                   char **excep_string,
-                                  char **cond_string)
+                                  std::string &cond_string)
 {
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   char *exception_name;
@@ -13055,7 +13181,13 @@ catch_ada_exception_command_split (const char *args,
 
   discard_cleanups (old_chain);
 
-  if (exception_name == NULL)
+  if (is_catch_handlers_cmd)
+    {
+      /* Catch handling of exceptions.  */
+      *ex = ada_catch_handlers;
+      *excep_string = exception_name;
+    }
+  else if (exception_name == NULL)
     {
       /* Catch all exceptions.  */
       *ex = ada_catch_exception;
@@ -13073,7 +13205,8 @@ catch_ada_exception_command_split (const char *args,
       *ex = ada_catch_exception;
       *excep_string = exception_name;
     }
-  *cond_string = cond;
+  if (cond != NULL)
+    cond_string.assign (cond);
 }
 
 /* Return the name of the symbol on which we should break in order to
@@ -13097,6 +13230,9 @@ ada_exception_sym_name (enum ada_exception_catchpoint_kind ex)
       case ada_catch_assert:
         return (data->exception_info->catch_assert_sym);
         break;
+      case ada_catch_handlers:
+        return (data->exception_info->catch_handlers_sym);
+        break;
       default:
         internal_error (__FILE__, __LINE__,
                         _("unexpected catchpoint kind (%d)"), ex);
@@ -13120,6 +13256,9 @@ ada_exception_breakpoint_ops (enum ada_exception_catchpoint_kind ex)
       case ada_catch_assert:
         return (&catch_assert_breakpoint_ops);
         break;
+      case ada_catch_handlers:
+        return (&catch_handlers_breakpoint_ops);
+        break;
       default:
         internal_error (__FILE__, __LINE__,
                         _("unexpected catchpoint kind (%d)"), ex);
@@ -13130,14 +13269,29 @@ ada_exception_breakpoint_ops (enum ada_exception_catchpoint_kind ex)
    being raised with the exception that the user wants to catch.  This
    assumes that this condition is used when the inferior just triggered
    an exception catchpoint.
+   EX: the type of catchpoints used for catching Ada exceptions.
    
    The string returned is a newly allocated string that needs to be
    deallocated later.  */
 
 static char *
-ada_exception_catchpoint_cond_string (const char *excep_string)
+ada_exception_catchpoint_cond_string (const char *excep_string,
+                                      enum ada_exception_catchpoint_kind ex)
 {
   int i;
+  bool is_standard_exc = false;
+  const char *actual_exc_expr;
+  char *ref_exc_expr;
+
+  if (ex == ada_catch_handlers)
+    {
+      /* For exception handlers catchpoints, the condition string does
+         not use the same parameter as for the other exceptions.  */
+      actual_exc_expr = ("long_integer (GNAT_GCC_exception_Access"
+                        "(gcc_exception).all.occurrence.id)");
+    }
+  else
+    actual_exc_expr = "long_integer (e)";
 
   /* The standard exceptions are a special case.  They are defined in
      runtime units that have been compiled without debugging info; if
@@ -13162,11 +13316,19 @@ ada_exception_catchpoint_cond_string (const char *excep_string)
     {
       if (strcmp (standard_exc [i], excep_string) == 0)
        {
-          return xstrprintf ("long_integer (e) = long_integer (&standard.%s)",
-                             excep_string);
+         is_standard_exc = true;
+         break;
        }
     }
-  return xstrprintf ("long_integer (e) = long_integer (&%s)", excep_string);
+
+  if (is_standard_exc)
+    ref_exc_expr = xstrprintf ("long_integer (&standard.%s)", excep_string);
+  else
+    ref_exc_expr = xstrprintf ("long_integer (&%s)", excep_string);
+
+  char *result =  xstrprintf ("%s = %s", actual_exc_expr, ref_exc_expr);
+  xfree (ref_exc_expr);
+  return result;
 }
 
 /* Return the symtab_and_line that should be used to insert an exception
@@ -13235,7 +13397,7 @@ void
 create_ada_exception_catchpoint (struct gdbarch *gdbarch,
                                 enum ada_exception_catchpoint_kind ex_kind,
                                 char *excep_string,
-                                char *cond_string,
+                                const std::string &cond_string,
                                 int tempflag,
                                 int disabled,
                                 int from_tty)
@@ -13249,9 +13411,9 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
   init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string,
                                 ops, tempflag, disabled, from_tty);
   c->excep_string = excep_string;
-  create_excep_cond_exprs (c.get ());
-  if (cond_string != NULL)
-    set_breakpoint_condition (c.get (), cond_string, from_tty);
+  create_excep_cond_exprs (c.get (), ex_kind);
+  if (!cond_string.empty ())
+    set_breakpoint_condition (c.get (), cond_string.c_str (), from_tty);
   install_breakpoint (0, std::move (c), 1);
 }
 
@@ -13266,14 +13428,39 @@ catch_ada_exception_command (const char *arg_entry, int from_tty,
   int tempflag;
   enum ada_exception_catchpoint_kind ex_kind;
   char *excep_string = NULL;
-  char *cond_string = NULL;
+  std::string cond_string;
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
-  catch_ada_exception_command_split (arg, &ex_kind, &excep_string,
-                                    &cond_string);
+  catch_ada_exception_command_split (arg, false, &ex_kind, &excep_string,
+                                    cond_string);
+  create_ada_exception_catchpoint (gdbarch, ex_kind,
+                                  excep_string, cond_string,
+                                  tempflag, 1 /* enabled */,
+                                  from_tty);
+}
+
+/* Implement the "catch handlers" command.  */
+
+static void
+catch_ada_handlers_command (const char *arg_entry, int from_tty,
+                           struct cmd_list_element *command)
+{
+  const char *arg = arg_entry;
+  struct gdbarch *gdbarch = get_current_arch ();
+  int tempflag;
+  enum ada_exception_catchpoint_kind ex_kind;
+  char *excep_string = NULL;
+  std::string cond_string;
+
+  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+
+  if (!arg)
+    arg = "";
+  catch_ada_exception_command_split (arg, true, &ex_kind, &excep_string,
+                                    cond_string);
   create_ada_exception_catchpoint (gdbarch, ex_kind,
                                   excep_string, cond_string,
                                   tempflag, 1 /* enabled */,
@@ -13289,7 +13476,7 @@ catch_ada_exception_command (const char *arg_entry, int from_tty,
    (the memory needs to be deallocated after use).  */
 
 static void
-catch_ada_assert_command_split (const char *args, char **cond_string)
+catch_ada_assert_command_split (const char *args, std::string &cond_string)
 {
   args = skip_spaces (args);
 
@@ -13301,7 +13488,7 @@ catch_ada_assert_command_split (const char *args, char **cond_string)
       args = skip_spaces (args);
       if (args[0] == '\0')
         error (_("condition missing after `if' keyword"));
-      *cond_string = xstrdup (args);
+      cond_string.assign (args);
     }
 
   /* Otherwise, there should be no other argument at the end of
@@ -13319,13 +13506,13 @@ catch_assert_command (const char *arg_entry, int from_tty,
   const char *arg = arg_entry;
   struct gdbarch *gdbarch = get_current_arch ();
   int tempflag;
-  char *cond_string = NULL;
+  std::string cond_string;
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
-  catch_ada_assert_command_split (arg, &cond_string);
+  catch_ada_assert_command_split (arg, cond_string);
   create_ada_exception_catchpoint (gdbarch, ada_catch_assert,
                                   NULL, cond_string,
                                   tempflag, 1 /* enabled */,
@@ -14235,12 +14422,38 @@ ada_symbol_name_matches (const char *symbol_search_name,
                                     comp_match_res);
 }
 
+/* A name matcher that matches the symbol name exactly, with
+   strcmp.  */
+
+static bool
+literal_symbol_name_matcher (const char *symbol_search_name,
+                            const lookup_name_info &lookup_name,
+                            completion_match_result *comp_match_res)
+{
+  const std::string &name = lookup_name.name ();
+
+  int cmp = (lookup_name.completion_mode ()
+            ? strncmp (symbol_search_name, name.c_str (), name.size ())
+            : strcmp (symbol_search_name, name.c_str ()));
+  if (cmp == 0)
+    {
+      if (comp_match_res != NULL)
+       comp_match_res->set_match (symbol_search_name);
+      return true;
+    }
+  else
+    return false;
+}
+
 /* Implement the "la_get_symbol_name_matcher" language_defn method for
    Ada.  */
 
 static symbol_name_matcher_ftype *
 ada_get_symbol_name_matcher (const lookup_name_info &lookup_name)
 {
+  if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
+    return literal_symbol_name_matcher;
+
   if (lookup_name.completion_mode ())
     return ada_symbol_name_matches;
   else
@@ -14304,6 +14517,7 @@ extern const struct language_defn ada_language_defn = {
   ada_read_var_value,          /* la_read_var_value */
   NULL,                         /* Language specific skip_trampoline */
   NULL,                         /* name_of_this */
+  true,                         /* la_store_sym_names_in_linkage_form_p */
   ada_lookup_symbol_nonlocal,   /* Looking up non-local symbols.  */
   basic_lookup_transparent_type,        /* lookup_transparent_type */
   ada_la_decode,                /* Language specific symbol demangler */
@@ -14387,6 +14601,16 @@ initialize_ada_catchpoint_ops (void)
   ops->print_one = print_one_catch_assert;
   ops->print_mention = print_mention_catch_assert;
   ops->print_recreate = print_recreate_catch_assert;
+
+  ops = &catch_handlers_breakpoint_ops;
+  *ops = bkpt_breakpoint_ops;
+  ops->allocate_location = allocate_location_catch_handlers;
+  ops->re_set = re_set_catch_handlers;
+  ops->check_status = check_status_catch_handlers;
+  ops->print_it = print_it_catch_handlers;
+  ops->print_one = print_one_catch_handlers;
+  ops->print_mention = print_mention_catch_handlers;
+  ops->print_recreate = print_recreate_catch_handlers;
 }
 
 /* This module's 'new_objfile' observer.  */
@@ -14447,6 +14671,14 @@ With an argument, catch only exceptions with the given name."),
                      NULL,
                     CATCH_PERMANENT,
                     CATCH_TEMPORARY);
+
+  add_catch_command ("handlers", _("\
+Catch Ada exceptions, when handled.\n\
+With an argument, catch only exceptions with the given name."),
+                    catch_ada_handlers_command,
+                     NULL,
+                    CATCH_PERMANENT,
+                    CATCH_TEMPORARY);
   add_catch_command ("assert", _("\
 Catch failed Ada assertions, when raised.\n\
 With an argument, catch only exceptions with the given name."),
@@ -14456,6 +14688,13 @@ With an argument, catch only exceptions with the given name."),
                     CATCH_TEMPORARY);
 
   varsize_limit = 65536;
+  add_setshow_uinteger_cmd ("varsize-limit", class_support,
+                           &varsize_limit, _("\
+Set the maximum number of bytes allowed in a variable-size object."), _("\
+Show the maximum number of bytes allowed in a variable-size object."), _("\
+Attempts to access an object whose size is not a compile-time constant\n\
+and exceeds this limit will cause an error."),
+                           NULL, NULL, &setlist, &showlist);
 
   add_info ("exceptions", info_exceptions_command,
            _("\
@@ -14488,9 +14727,9 @@ DWARF attribute."),
      NULL, xcalloc, xfree);
 
   /* The ada-lang observers.  */
-  observer_attach_new_objfile (ada_new_objfile_observer);
-  observer_attach_free_objfile (ada_free_objfile_observer);
-  observer_attach_inferior_exit (ada_inferior_exit);
+  gdb::observers::new_objfile.attach (ada_new_objfile_observer);
+  gdb::observers::free_objfile.attach (ada_free_objfile_observer);
+  gdb::observers::inferior_exit.attach (ada_inferior_exit);
 
   /* Setup various context-specific data.  */
   ada_inferior_data
This page took 0.043768 seconds and 4 git commands to generate.