mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 18:44:20 +08:00
Add command to list Ada exceptions
This patch adds a new command "info exceptions" whose purpose is to provide the list of exceptions currently defined in the inferior. The usage is: (gdb) info exceptions [REGEXP] Without argument, the command lists all exceptions. Otherwise, only those whose name match REGEXP are listed. For instance: (gdb) info exceptions All defined Ada exceptions: constraint_error: 0x613dc0 program_error: 0x613d40 storage_error: 0x613d00 tasking_error: 0x613cc0 global_exceptions.a_global_exception: 0x613a80 global_exceptions.a_private_exception: 0x613ac0 The name of the command, as well as its output is part of a legacy I inherited long ago. It's output being parsed by frontends such as GPS, I cannot easily change it. Same for the command name. The implementation is mostly self-contained, and is written in a way that should make it easy to implement the GDB/MI equivalent. The careful reviewer will notice that the code added in ada-lang.h could normally be made private inside ada-lang.c. But these will be used by the GDB/MI implementation. Rather than making those private now, only to move them later, I've made them public right away. gdb/ChangeLog: * ada-lang.h: #include "vec.h". (struct ada_exc_info): New. (ada_exc_info): New typedef. (DEF_VEC_O(ada_exc_info)): New vector. (ada_exceptions_list): Add declaration. * ada-lang.c (ada_is_exception_sym) (ada_is_non_standard_exception_sym, compare_ada_exception_info) (sort_remove_dups_ada_exceptions_list) (ada_exc_search_name_matches, ada_add_standard_exceptions) (ada_add_exceptions_from_frame, ada_add_global_exceptions) (ada_exceptions_list_1, ada_exceptions_list) (info_exceptions_command): New function. (_initialize_ada_language): Add "info exception" command. gdb/testsuite/ChangeLog: * gdb.ada/info_exc: New testcase.
This commit is contained in:
parent
304a8ac17c
commit
778865d3e2
@ -1,3 +1,19 @@
|
||||
2013-11-12 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* ada-lang.h: #include "vec.h".
|
||||
(struct ada_exc_info): New.
|
||||
(ada_exc_info): New typedef.
|
||||
(DEF_VEC_O(ada_exc_info)): New vector.
|
||||
(ada_exceptions_list): Add declaration.
|
||||
* ada-lang.c (ada_is_exception_sym)
|
||||
(ada_is_non_standard_exception_sym, compare_ada_exception_info)
|
||||
(sort_remove_dups_ada_exceptions_list)
|
||||
(ada_exc_search_name_matches, ada_add_standard_exceptions)
|
||||
(ada_add_exceptions_from_frame, ada_add_global_exceptions)
|
||||
(ada_exceptions_list_1, ada_exceptions_list)
|
||||
(info_exceptions_command): New function.
|
||||
(_initialize_ada_language): Add "info exception" command.
|
||||
|
||||
2013-11-11 Phil Muldoon <pmuldoon@redhat.com>
|
||||
|
||||
PR python/15629
|
||||
|
357
gdb/ada-lang.c
357
gdb/ada-lang.c
@ -12284,6 +12284,357 @@ catch_assert_command (char *arg, int from_tty,
|
||||
tempflag, 1 /* enabled */,
|
||||
from_tty);
|
||||
}
|
||||
|
||||
/* Return non-zero if the symbol SYM is an Ada exception object. */
|
||||
|
||||
static int
|
||||
ada_is_exception_sym (struct symbol *sym)
|
||||
{
|
||||
const char *type_name = type_name_no_tag (SYMBOL_TYPE (sym));
|
||||
|
||||
return (SYMBOL_CLASS (sym) != LOC_TYPEDEF
|
||||
&& SYMBOL_CLASS (sym) != LOC_BLOCK
|
||||
&& SYMBOL_CLASS (sym) != LOC_CONST
|
||||
&& SYMBOL_CLASS (sym) != LOC_UNRESOLVED
|
||||
&& type_name != NULL && strcmp (type_name, "exception") == 0);
|
||||
}
|
||||
|
||||
/* Given a global symbol SYM, return non-zero iff SYM is a non-standard
|
||||
Ada exception object. This matches all exceptions except the ones
|
||||
defined by the Ada language. */
|
||||
|
||||
static int
|
||||
ada_is_non_standard_exception_sym (struct symbol *sym)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ada_is_exception_sym (sym))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
|
||||
if (strcmp (SYMBOL_LINKAGE_NAME (sym), standard_exc[i]) == 0)
|
||||
return 0; /* A standard exception. */
|
||||
|
||||
/* Numeric_Error is also a standard exception, so exclude it.
|
||||
See the STANDARD_EXC description for more details as to why
|
||||
this exception is not listed in that array. */
|
||||
if (strcmp (SYMBOL_LINKAGE_NAME (sym), "numeric_error") == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A helper function for qsort, comparing two struct ada_exc_info
|
||||
objects.
|
||||
|
||||
The comparison is determined first by exception name, and then
|
||||
by exception address. */
|
||||
|
||||
static int
|
||||
compare_ada_exception_info (const void *a, const void *b)
|
||||
{
|
||||
const struct ada_exc_info *exc_a = (struct ada_exc_info *) a;
|
||||
const struct ada_exc_info *exc_b = (struct ada_exc_info *) b;
|
||||
int result;
|
||||
|
||||
result = strcmp (exc_a->name, exc_b->name);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
if (exc_a->addr < exc_b->addr)
|
||||
return -1;
|
||||
if (exc_a->addr > exc_b->addr)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sort EXCEPTIONS using compare_ada_exception_info as the comparison
|
||||
routine, but keeping the first SKIP elements untouched.
|
||||
|
||||
All duplicates are also removed. */
|
||||
|
||||
static void
|
||||
sort_remove_dups_ada_exceptions_list (VEC(ada_exc_info) **exceptions,
|
||||
int skip)
|
||||
{
|
||||
struct ada_exc_info *to_sort
|
||||
= VEC_address (ada_exc_info, *exceptions) + skip;
|
||||
int to_sort_len
|
||||
= VEC_length (ada_exc_info, *exceptions) - skip;
|
||||
int i, j;
|
||||
|
||||
qsort (to_sort, to_sort_len, sizeof (struct ada_exc_info),
|
||||
compare_ada_exception_info);
|
||||
|
||||
for (i = 1, j = 1; i < to_sort_len; i++)
|
||||
if (compare_ada_exception_info (&to_sort[i], &to_sort[j - 1]) != 0)
|
||||
to_sort[j++] = to_sort[i];
|
||||
to_sort_len = j;
|
||||
VEC_truncate(ada_exc_info, *exceptions, skip + to_sort_len);
|
||||
}
|
||||
|
||||
/* A function intended as the "name_matcher" callback in the struct
|
||||
quick_symbol_functions' expand_symtabs_matching method.
|
||||
|
||||
SEARCH_NAME is the symbol's search name.
|
||||
|
||||
If USER_DATA is not NULL, it is a pointer to a regext_t object
|
||||
used to match the symbol (by natural name). Otherwise, when USER_DATA
|
||||
is null, no filtering is performed, and all symbols are a positive
|
||||
match. */
|
||||
|
||||
static int
|
||||
ada_exc_search_name_matches (const char *search_name, void *user_data)
|
||||
{
|
||||
regex_t *preg = user_data;
|
||||
|
||||
if (preg == NULL)
|
||||
return 1;
|
||||
|
||||
/* In Ada, the symbol "search name" is a linkage name, whereas
|
||||
the regular expression used to do the matching refers to
|
||||
the natural name. So match against the decoded name. */
|
||||
return (regexec (preg, ada_decode (search_name), 0, NULL, 0) == 0);
|
||||
}
|
||||
|
||||
/* Add all exceptions defined by the Ada standard whose name match
|
||||
a regular expression.
|
||||
|
||||
If PREG is not NULL, then this regexp_t object is used to
|
||||
perform the symbol name matching. Otherwise, no name-based
|
||||
filtering is performed.
|
||||
|
||||
EXCEPTIONS is a vector of exceptions to which matching exceptions
|
||||
gets pushed. */
|
||||
|
||||
static void
|
||||
ada_add_standard_exceptions (regex_t *preg, VEC(ada_exc_info) **exceptions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (standard_exc); i++)
|
||||
{
|
||||
if (preg == NULL
|
||||
|| regexec (preg, standard_exc[i], 0, NULL, 0) == 0)
|
||||
{
|
||||
struct bound_minimal_symbol msymbol
|
||||
= ada_lookup_simple_minsym (standard_exc[i]);
|
||||
|
||||
if (msymbol.minsym != NULL)
|
||||
{
|
||||
struct ada_exc_info info
|
||||
= {standard_exc[i], SYMBOL_VALUE_ADDRESS (msymbol.minsym)};
|
||||
|
||||
VEC_safe_push (ada_exc_info, *exceptions, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add all Ada exceptions defined locally and accessible from the given
|
||||
FRAME.
|
||||
|
||||
If PREG is not NULL, then this regexp_t object is used to
|
||||
perform the symbol name matching. Otherwise, no name-based
|
||||
filtering is performed.
|
||||
|
||||
EXCEPTIONS is a vector of exceptions to which matching exceptions
|
||||
gets pushed. */
|
||||
|
||||
static void
|
||||
ada_add_exceptions_from_frame (regex_t *preg, struct frame_info *frame,
|
||||
VEC(ada_exc_info) **exceptions)
|
||||
{
|
||||
struct block *block = get_frame_block (frame, 0);
|
||||
|
||||
while (block != 0)
|
||||
{
|
||||
struct block_iterator iter;
|
||||
struct symbol *sym;
|
||||
|
||||
ALL_BLOCK_SYMBOLS (block, iter, sym)
|
||||
{
|
||||
switch (SYMBOL_CLASS (sym))
|
||||
{
|
||||
case LOC_TYPEDEF:
|
||||
case LOC_BLOCK:
|
||||
case LOC_CONST:
|
||||
break;
|
||||
default:
|
||||
if (ada_is_exception_sym (sym))
|
||||
{
|
||||
struct ada_exc_info info = {SYMBOL_PRINT_NAME (sym),
|
||||
SYMBOL_VALUE_ADDRESS (sym)};
|
||||
|
||||
VEC_safe_push (ada_exc_info, *exceptions, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (BLOCK_FUNCTION (block) != NULL)
|
||||
break;
|
||||
block = BLOCK_SUPERBLOCK (block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add all exceptions defined globally whose name name match
|
||||
a regular expression, excluding standard exceptions.
|
||||
|
||||
The reason we exclude standard exceptions is that they need
|
||||
to be handled separately: Standard exceptions are defined inside
|
||||
a runtime unit which is normally not compiled with debugging info,
|
||||
and thus usually do not show up in our symbol search. However,
|
||||
if the unit was in fact built with debugging info, we need to
|
||||
exclude them because they would duplicate the entry we found
|
||||
during the special loop that specifically searches for those
|
||||
standard exceptions.
|
||||
|
||||
If PREG is not NULL, then this regexp_t object is used to
|
||||
perform the symbol name matching. Otherwise, no name-based
|
||||
filtering is performed.
|
||||
|
||||
EXCEPTIONS is a vector of exceptions to which matching exceptions
|
||||
gets pushed. */
|
||||
|
||||
static void
|
||||
ada_add_global_exceptions (regex_t *preg, VEC(ada_exc_info) **exceptions)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
struct symtab *s;
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
if (objfile->sf)
|
||||
objfile->sf->qf->expand_symtabs_matching
|
||||
(objfile, NULL, ada_exc_search_name_matches,
|
||||
VARIABLES_DOMAIN, preg);
|
||||
|
||||
ALL_PRIMARY_SYMTABS (objfile, s)
|
||||
{
|
||||
struct blockvector *bv = BLOCKVECTOR (s);
|
||||
int i;
|
||||
|
||||
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
|
||||
{
|
||||
struct block *b = BLOCKVECTOR_BLOCK (bv, i);
|
||||
struct block_iterator iter;
|
||||
struct symbol *sym;
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
if (ada_is_non_standard_exception_sym (sym)
|
||||
&& (preg == NULL
|
||||
|| regexec (preg, SYMBOL_NATURAL_NAME (sym),
|
||||
0, NULL, 0) == 0))
|
||||
{
|
||||
struct ada_exc_info info
|
||||
= {SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE_ADDRESS (sym)};
|
||||
|
||||
VEC_safe_push (ada_exc_info, *exceptions, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Implements ada_exceptions_list with the regular expression passed
|
||||
as a regex_t, rather than a string.
|
||||
|
||||
If not NULL, PREG is used to filter out exceptions whose names
|
||||
do not match. Otherwise, all exceptions are listed. */
|
||||
|
||||
static VEC(ada_exc_info) *
|
||||
ada_exceptions_list_1 (regex_t *preg)
|
||||
{
|
||||
VEC(ada_exc_info) *result = NULL;
|
||||
struct cleanup *old_chain
|
||||
= make_cleanup (VEC_cleanup (ada_exc_info), &result);
|
||||
int prev_len;
|
||||
|
||||
/* First, list the known standard exceptions. These exceptions
|
||||
need to be handled separately, as they are usually defined in
|
||||
runtime units that have been compiled without debugging info. */
|
||||
|
||||
ada_add_standard_exceptions (preg, &result);
|
||||
|
||||
/* Next, find all exceptions whose scope is local and accessible
|
||||
from the currently selected frame. */
|
||||
|
||||
if (has_stack_frames ())
|
||||
{
|
||||
prev_len = VEC_length (ada_exc_info, result);
|
||||
ada_add_exceptions_from_frame (preg, get_selected_frame (NULL),
|
||||
&result);
|
||||
if (VEC_length (ada_exc_info, result) > prev_len)
|
||||
sort_remove_dups_ada_exceptions_list (&result, prev_len);
|
||||
}
|
||||
|
||||
/* Add all exceptions whose scope is global. */
|
||||
|
||||
prev_len = VEC_length (ada_exc_info, result);
|
||||
ada_add_global_exceptions (preg, &result);
|
||||
if (VEC_length (ada_exc_info, result) > prev_len)
|
||||
sort_remove_dups_ada_exceptions_list (&result, prev_len);
|
||||
|
||||
discard_cleanups (old_chain);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a vector of ada_exc_info.
|
||||
|
||||
If REGEXP is NULL, all exceptions are included in the result.
|
||||
Otherwise, it should contain a valid regular expression,
|
||||
and only the exceptions whose names match that regular expression
|
||||
are included in the result.
|
||||
|
||||
The exceptions are sorted in the following order:
|
||||
- Standard exceptions (defined by the Ada language), in
|
||||
alphabetical order;
|
||||
- Exceptions only visible from the current frame, in
|
||||
alphabetical order;
|
||||
- Exceptions whose scope is global, in alphabetical order. */
|
||||
|
||||
VEC(ada_exc_info) *
|
||||
ada_exceptions_list (const char *regexp)
|
||||
{
|
||||
VEC(ada_exc_info) *result = NULL;
|
||||
struct cleanup *old_chain = NULL;
|
||||
regex_t reg;
|
||||
|
||||
if (regexp != NULL)
|
||||
old_chain = compile_rx_or_error (®, regexp,
|
||||
_("invalid regular expression"));
|
||||
|
||||
result = ada_exceptions_list_1 (regexp != NULL ? ® : NULL);
|
||||
|
||||
if (old_chain != NULL)
|
||||
do_cleanups (old_chain);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Implement the "info exceptions" command. */
|
||||
|
||||
static void
|
||||
info_exceptions_command (char *regexp, int from_tty)
|
||||
{
|
||||
VEC(ada_exc_info) *exceptions;
|
||||
struct cleanup *cleanup;
|
||||
struct gdbarch *gdbarch = get_current_arch ();
|
||||
int ix;
|
||||
struct ada_exc_info *info;
|
||||
|
||||
exceptions = ada_exceptions_list (regexp);
|
||||
cleanup = make_cleanup (VEC_cleanup (ada_exc_info), &exceptions);
|
||||
|
||||
if (regexp != NULL)
|
||||
printf_filtered
|
||||
(_("All Ada exceptions matching regular expression \"%s\":\n"), regexp);
|
||||
else
|
||||
printf_filtered (_("All defined Ada exceptions:\n"));
|
||||
|
||||
for (ix = 0; VEC_iterate(ada_exc_info, exceptions, ix, info); ix++)
|
||||
printf_filtered ("%s: %s\n", info->name, paddress (gdbarch, info->addr));
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
|
||||
/* Operators */
|
||||
/* Information about operators given special treatment in functions
|
||||
below. */
|
||||
@ -12956,6 +13307,12 @@ With an argument, catch only exceptions with the given name."),
|
||||
|
||||
varsize_limit = 65536;
|
||||
|
||||
add_info ("exceptions", info_exceptions_command,
|
||||
_("\
|
||||
List all Ada exception names.\n\
|
||||
If a regular expression is passed as an argument, only those matching\n\
|
||||
the regular expression are listed."));
|
||||
|
||||
obstack_init (&symbol_list_obstack);
|
||||
|
||||
decoded_names_store = htab_create_alloc
|
||||
|
@ -27,6 +27,7 @@ struct type_print_options;
|
||||
#include "value.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "breakpoint.h"
|
||||
#include "vec.h"
|
||||
|
||||
/* Names of specific files known to be part of the runtime
|
||||
system and that might consider (confusing) debugging information.
|
||||
@ -389,6 +390,21 @@ extern void create_ada_exception_catchpoint
|
||||
char *excep_string, char *cond_string, int tempflag, int disabled,
|
||||
int from_tty);
|
||||
|
||||
/* Some information about a given Ada exception. */
|
||||
|
||||
typedef struct ada_exc_info
|
||||
{
|
||||
/* The name of the exception. */
|
||||
const char *name;
|
||||
|
||||
/* The address of the symbol corresponding to that exception. */
|
||||
CORE_ADDR addr;
|
||||
} ada_exc_info;
|
||||
|
||||
DEF_VEC_O(ada_exc_info);
|
||||
|
||||
extern VEC(ada_exc_info) *ada_exceptions_list (const char *regexp);
|
||||
|
||||
/* Tasking-related: ada-tasks.c */
|
||||
|
||||
extern int valid_task_id (int);
|
||||
|
@ -1,3 +1,7 @@
|
||||
2013-11-12 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.ada/info_exc: New testcase.
|
||||
|
||||
2013-11-11 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.arch/arm-bl-branch-dest.exp: Use gdb_test_file_name instead
|
||||
|
57
gdb/testsuite/gdb.ada/info_exc.exp
Normal file
57
gdb/testsuite/gdb.ada/info_exc.exp
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright 2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "ada.exp"
|
||||
|
||||
standard_ada_testfile foo
|
||||
|
||||
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# A convenience function that joins all the arguments together,
|
||||
# with a regexp that matches zero-or-more end of lines in between
|
||||
# each argument. This function is ideal to write the expected output
|
||||
# of a GDB command that generates more than a couple of lines, as
|
||||
# this allows us to write each line as a separate string, which is
|
||||
# easier to read by a human being.
|
||||
|
||||
proc multi_line { args } {
|
||||
return [join $args "\[\r\n\]*"]
|
||||
}
|
||||
|
||||
clean_restart ${testfile}
|
||||
|
||||
gdb_test "info exceptions" \
|
||||
[multi_line "All defined Ada exceptions:" \
|
||||
"constraint_error: $hex" \
|
||||
"program_error: $hex" \
|
||||
"storage_error: $hex" \
|
||||
"tasking_error: $hex" \
|
||||
"const.aint_global_e: $hex"]
|
||||
|
||||
gdb_test "info exceptions task" \
|
||||
[multi_line "All Ada exceptions matching regular expression \"task\":" \
|
||||
"tasking_error: $hex"]
|
||||
|
||||
gdb_test "info exceptions global" \
|
||||
[multi_line "All Ada exceptions matching regular expression \"global\":" \
|
||||
"const.aint_global_e: $hex"]
|
||||
|
||||
gdb_test "info exceptions const.aint" \
|
||||
[multi_line "All Ada exceptions matching regular expression \"const\\.aint\":" \
|
||||
"constraint_error: $hex" \
|
||||
"const.aint_global_e: $hex"]
|
||||
|
18
gdb/testsuite/gdb.ada/info_exc/const.ads
Normal file
18
gdb/testsuite/gdb.ada/info_exc/const.ads
Normal file
@ -0,0 +1,18 @@
|
||||
-- Copyright 2013 Free Software Foundation, Inc.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package Const is
|
||||
Aint_Global_E : exception;
|
||||
end Const;
|
20
gdb/testsuite/gdb.ada/info_exc/foo.adb
Normal file
20
gdb/testsuite/gdb.ada/info_exc/foo.adb
Normal file
@ -0,0 +1,20 @@
|
||||
-- Copyright 2013 Free Software Foundation, Inc.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
with Const; use Const;
|
||||
procedure Foo is
|
||||
begin
|
||||
raise Aint_Global_E;
|
||||
end Foo;
|
Loading…
Reference in New Issue
Block a user