From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12738 invoked by alias); 26 Jul 2015 09:30:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 12712 invoked by uid 89); 26 Jul 2015 09:30:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.5 required=5.0 tests=AWL,BAYES_50,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f49.google.com Received: from mail-pa0-f49.google.com (HELO mail-pa0-f49.google.com) (209.85.220.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 26 Jul 2015 09:30:42 +0000 Received: by pachj5 with SMTP id hj5so35632012pac.3 for ; Sun, 26 Jul 2015 02:30:40 -0700 (PDT) X-Received: by 10.66.90.166 with SMTP id bx6mr53501610pab.76.1437903040379; Sun, 26 Jul 2015 02:30:40 -0700 (PDT) Received: from seba.sebabeach.org.gmail.com (173-13-178-53-sfba.hfc.comcastbusiness.net. [173.13.178.53]) by smtp.gmail.com with ESMTPSA id y6sm18207824pdl.61.2015.07.26.02.30.38 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Jul 2015 02:30:39 -0700 (PDT) From: Doug Evans To: Pierre-Marie de Rodat Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] [Ada] Add support for subprogram renamings References: <1437854144-31928-1-git-send-email-derodat@adacore.com> Date: Sun, 26 Jul 2015 09:30:00 -0000 In-Reply-To: <1437854144-31928-1-git-send-email-derodat@adacore.com> (Pierre-Marie de Rodat's message of "Sat, 25 Jul 2015 21:55:44 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2015-07/txt/msg00768.txt.bz2 Pierre-Marie de Rodat writes: > Consider the following declaration: > > function Foo (I : Integer) return Integer renames Pack.Bar; > > As Foo is not materialized as a routine whose name is derived from Foo, > GDB currently cannot use it: > > (gdb) print foo(0) > No definition of "foo" in current context. > > However, compilers can emit DW_TAG_imported_declaration in order to > materialize the fact that Foo is actually another name for Pack.Bar. > This commit enhances the DWARF reader to record global renamings (it > used to put global ones in a static block) and enhances the Ada engine > to leverage this information during symbol lookup. Hi. A few nits inline, grep for ====. > gdb/ChangeLog: > > * ada-lang.c: Include cp-support.h ada-foo including cp-foo? We need to clean this up. Things are even muddier as this stuff is recorded in block.language_specific.cplus_specific, so cleaning this up now will be good. I gather cp-support.h is needed here for struct using_direct. I think (at least) three things need to happen. 1) Move the definition of struct using_direct out of cp-support.h. 2) Move the definition of cp_add_using_directive out of cp-namespace.c. And delete the leading "cp_". 3) Reorg block.language_specific. For the first two I'd be ok with lang-support.[ch]. Yeah, it'll be a small file for now, but that's ok IMO. Alternatives are language.[ch] or block.[ch]. For (3), in the absence of needing anything more at the moment, I'd be ok with replacing: union { struct { /* Contains information about namespace-related info relevant to this block: using directives and the current namespace scope. */ struct block_namespace_info *the_namespace; } cplus_specific; } language_specific; with just: /* Contains information about namespace-related info relevant to this block: using directives and the current namespace scope. */ struct block_namespace_info *the_namespace; though I'd probably rename "the_namespace" to "namespace_info" or some such. > (aux_add_nonlocal_symbols): Fix a function name in comment. > (ada_add_block_renamings): New. > (add_nonlocal_symbols): Add global renamings handling. > (ada_lookup_symbol_list_worker): Move the symbol lookup part > to... > (ada_add_all_symbols): ... this new function. > (ada_add_block_symbols): Try to match the input name against the > "using directives list", perform a recursive symbol lookup on > the matched declarations. > * buildsym.h (using_directives): Rename into... > (local_using_directives): ... this. > (global_using_directives): New. > (struct context_stack): Rename the using_directives field into > local_using_directives. > * buildsym.c (finish_block_internal): Deal with the proper > using directives repository (local or global). > (prepare_for_building): Assert that there is no pending global > using directive. > (reset_symtab_globals): Reset global_using_directives. > (end_symtab_get_static_block): Don't ignore symtabs that have > only using directives. > (push_context): Update references to local_using_directives. > (buildsym_init): Likewise. > * cp-support.h (cp_add_using_directives): Add a > "using_directives" argument. > * cp-namespace.c (cp_add_using_directive): Add a > "using_directives" argument and use it as the pending using > directives repository. ==== Missing "All callers updated." > (cp_scan_for_anonymous_namespaces): Update call to > cp_add_using_directive. ==== Don't write individual changelog entries for updates to function calls. Instead, just write "All callers updated." at the description of the function that was changed. > * dwarf2read.c (read_import_statement): Likewise. > (read_namespace): Likewise. > (read_func_scope): Update references to local_using_directives. > (read_lexical_block_scope): Likewise. > > gdb/testsuite/ChangeLog: > > * gdb.ada/fun_renaming.exp: New testcase. > * gdb.ada/fun_renaming/fun_renaming.adb: New file. > * gdb.ada/fun_renaming/pack.adb: New file. > * gdb.ada/fun_renaming/pack.ads: New file. > > Tested on x86_64-linux. Support for this in GCC is in the pipeline: see > . > ... > > diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c > index 06c72ee..c313fa8 100644 > --- a/gdb/ada-lang.c > +++ b/gdb/ada-lang.c > @@ -53,6 +53,7 @@ > #include "stack.h" > #include "gdb_vecs.h" > #include "typeprint.h" > +#include "cp-support.h" > > #include "psymtab.h" > #include "value.h" > @@ -108,6 +109,9 @@ static void ada_add_block_symbols (struct obstack *, > const struct block *, const char *, > domain_enum, struct objfile *, int); > > +static void ada_add_all_symbols (struct obstack *, const struct block *, > + const char *, domain_enum, int, int *); > + > static int is_nonfunction (struct ada_symbol_info *, int); > > static void add_defn_to_vec (struct obstack *, struct symbol *, > @@ -5288,7 +5292,7 @@ struct match_data > int found_sym; > }; > > -/* A callback for add_matching_symbols that adds SYM, found in BLOCK, > +/* A callback for add_nonlocal_symbols that adds SYM, found in BLOCK, > to a list of symbols. DATA0 is a pointer to a struct match_data * > containing the obstack that collects the symbol list, the file that SYM > must come from, a flag indicating whether a non-argument symbol has > @@ -5328,6 +5332,62 @@ aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0) > return 0; > } > > +/* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are targetted > + by renamings matching NAME in BLOCK. Add these symbols to OBSTACKP. If > + WILD_MATCH_P is nonzero, perform the naming matching in "wild" mode (see > + function "wild_match" for more information). Return whether we found such > + symbols. */ > + > +static int > +ada_add_block_renamings (struct obstack *obstackp, > + const struct block *block, > + const char *name, > + domain_enum domain, > + int wild_match_p) > +{ > + struct using_direct *renaming; > + int defns_mark = num_defns_collected (obstackp); > + > + for (renaming = block_using (block); > + renaming != NULL; > + renaming = renaming->next) > + { > + const char *r_name; > + int name_match; > + > + /* Avoid infinite recursions: skip this renaming if we are actually > + already traversing it. > + > + Currently, symbol lookup in Ada don't use the namespace machinery from > + C++/Fortran support: skip namespace imports that use them. */ > + if (renaming->searched > + || (renaming->import_src != NULL > + && renaming->import_src[0] != '\0') > + || (renaming->import_dest != NULL > + && renaming->import_dest[0] != '\0')) > + continue; > + renaming->searched = 1; > + > + /* TODO: here, we perform another name-based symbol lookup, which can > + pull its own multiple overloads. In theory, we should be able to do > + better in this case since, in DWARF, DW_AT_import is a DIE reference, > + not a simple name. But in order to do this, we would need to enhance > + the DWARF reader to associate a symbol to this renaming, instead of a > + name. So, for now, we do something simpler: re-use the C++/Fortran > + namespace machinery. */ > + r_name = (renaming->alias != NULL > + ? renaming->alias > + : renaming->declaration); > + name_match > + = wild_match_p ? wild_match (r_name, name) : strcmp (r_name, name); > + if (name_match == 0) > + ada_add_all_symbols (obstackp, block, renaming->declaration, domain, > + 1, NULL); > + renaming->searched = 0; > + } > + return num_defns_collected (obstackp) != defns_mark; > +} > + > /* Implements compare_names, but only applying the comparision using > the given CASING. */ > > @@ -5423,6 +5483,7 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name, > int is_wild_match) > { > struct objfile *objfile; > + struct compunit_symtab *cu; > struct match_data data; > > memset (&data, 0, sizeof data); > @@ -5440,6 +5501,16 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name, > objfile->sf->qf->map_matching_symbols (objfile, name, domain, global, > aux_add_nonlocal_symbols, &data, > full_match, compare_names); > + > + ALL_OBJFILE_COMPUNITS (objfile, cu) > + { > + const struct block *global_block > + = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK); > + > + if (ada_add_block_renamings (obstackp, global_block , name, domain, > + is_wild_match)) > + data.found_sym = 1; > + } > } > > if (num_defns_collected (obstackp) == 0 && global && !is_wild_match) > @@ -5459,43 +5530,35 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name, > } > } > > -/* Find symbols in DOMAIN matching NAME0, in BLOCK0 and, if full_search is > +/* Find symbols in DOMAIN matching NAME, in BLOCK and, if FULL_SEARCH is > non-zero, enclosing scope and in global scopes, returning the number of > - matches. > - Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples, > - indicating the symbols found and the blocks and symbol tables (if > - any) in which they were found. This vector is transient---good only to > - the next call of ada_lookup_symbol_list. > + matches. Add these to OBSTACKP. > > - When full_search is non-zero, any non-function/non-enumeral > - symbol match within the nest of blocks whose innermost member is BLOCK0, > + When FULL_SEARCH is non-zero, any non-function/non-enumeral > + symbol match within the nest of blocks whose innermost member is BLOCK, > is the one match returned (no other matches in that or > enclosing blocks is returned). If there are any matches in or > - surrounding BLOCK0, then these alone are returned. > + surrounding BLOCK, then these alone are returned. > > Names prefixed with "standard__" are handled specially: "standard__" > - is first stripped off, and only static and global symbols are searched. */ > + is first stripped off, and only static and global symbols are searched. > > -static int > -ada_lookup_symbol_list_worker (const char *name0, const struct block *block0, > - domain_enum domain, > - struct ada_symbol_info **results, > - int full_search) > + If MADE_GLOBAL_LOOKUP_P is non-null, set it before return to whether we had > + to lookup global symbols. */ > + > +static void > +ada_add_all_symbols (struct obstack *obstackp, > + const struct block *block, > + const char *name, > + domain_enum domain, > + int full_search, > + int *made_global_lookup_p) > { > struct symbol *sym; > - const struct block *block; > - const char *name; > - const int wild_match_p = should_use_wild_match (name0); > - int syms_from_global_search = 0; > - int ndefns; > - > - obstack_free (&symbol_list_obstack, NULL); > - obstack_init (&symbol_list_obstack); > - > - /* Search specified block and its superiors. */ > + const int wild_match_p = should_use_wild_match (name); > > - name = name0; > - block = block0; > + if (made_global_lookup_p) > + *made_global_lookup_p = 0; > > /* Special case: If the user specifies a symbol name inside package > Standard, do a non-wild matching of the symbol name without > @@ -5504,10 +5567,10 @@ ada_lookup_symbol_list_worker (const char *name0, const struct block *block0, > using, for instance, Standard.Constraint_Error when Constraint_Error > is ambiguous (due to the user defining its own Constraint_Error > entity inside its program). */ > - if (startswith (name0, "standard__")) > + if (startswith (name, "standard__")) > { > block = NULL; > - name = name0 + sizeof ("standard__") - 1; > + name = name + sizeof ("standard__") - 1; > } > > /* Check the non-global symbols. If we have ANY match, then we're done. */ > @@ -5515,61 +5578,88 @@ ada_lookup_symbol_list_worker (const char *name0, const struct block *block0, > if (block != NULL) > { > if (full_search) > - { > - ada_add_local_symbols (&symbol_list_obstack, name, block, > - domain, wild_match_p); > - } > + ada_add_local_symbols (obstackp, name, block, domain, wild_match_p); > else > { > /* In the !full_search case we're are being called by > ada_iterate_over_symbols, and we don't want to search > superblocks. */ > - ada_add_block_symbols (&symbol_list_obstack, block, name, > - domain, NULL, wild_match_p); > + ada_add_block_symbols (obstackp, block, name, domain, NULL, > + wild_match_p); > } > - if (num_defns_collected (&symbol_list_obstack) > 0 || !full_search) > - goto done; > + if (num_defns_collected (obstackp) > 0 || !full_search) > + return; > } > > /* No non-global symbols found. Check our cache to see if we have > already performed this search before. If we have, then return > the same result. */ > > - if (lookup_cached_symbol (name0, domain, &sym, &block)) > + if (lookup_cached_symbol (name, domain, &sym, &block)) > { > if (sym != NULL) > - add_defn_to_vec (&symbol_list_obstack, sym, block); > - goto done; > + add_defn_to_vec (obstackp, sym, block); > + return; > } > > - syms_from_global_search = 1; > + if (made_global_lookup_p) > + *made_global_lookup_p = 1; > > /* Search symbols from all global blocks. */ > > - add_nonlocal_symbols (&symbol_list_obstack, name, domain, 1, > - wild_match_p); > + add_nonlocal_symbols (obstackp, name, domain, 1, wild_match_p); > > /* Now add symbols from all per-file blocks if we've gotten no hits > (not strictly correct, but perhaps better than an error). */ > > - if (num_defns_collected (&symbol_list_obstack) == 0) > - add_nonlocal_symbols (&symbol_list_obstack, name, domain, 0, > - wild_match_p); > + if (num_defns_collected (obstackp) == 0) > + add_nonlocal_symbols (obstackp, name, domain, 0, wild_match_p); > +} > + > +/* Find symbols in DOMAIN matching NAME, in BLOCK and, if full_search is > + non-zero, enclosing scope and in global scopes, returning the number of > + matches. > + Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples, > + indicating the symbols found and the blocks and symbol tables (if > + any) in which they were found. This vector is transient---good only to > + the next call of ada_lookup_symbol_list. > + > + When full_search is non-zero, any non-function/non-enumeral > + symbol match within the nest of blocks whose innermost member is BLOCK, > + is the one match returned (no other matches in that or > + enclosing blocks is returned). If there are any matches in or > + surrounding BLOCK, then these alone are returned. > + > + Names prefixed with "standard__" are handled specially: "standard__" > + is first stripped off, and only static and global symbols are searched. */ > + > +static int > +ada_lookup_symbol_list_worker (const char *name, const struct block *block, > + domain_enum domain, > + struct ada_symbol_info **results, > + int full_search) > +{ > + const int wild_match_p = should_use_wild_match (name); > + int syms_from_global_search; > + int ndefns; > + > + obstack_free (&symbol_list_obstack, NULL); > + obstack_init (&symbol_list_obstack); > + ada_add_all_symbols (&symbol_list_obstack, block, name, domain, > + full_search, &syms_from_global_search); > > -done: > ndefns = num_defns_collected (&symbol_list_obstack); > *results = defns_collected (&symbol_list_obstack, 1); > > ndefns = remove_extra_symbols (*results, ndefns); > > if (ndefns == 0 && full_search && syms_from_global_search) > - cache_symbol (name0, domain, NULL, NULL); > + cache_symbol (name, domain, NULL, NULL); > > if (ndefns == 1 && full_search && syms_from_global_search) > - cache_symbol (name0, domain, (*results)[0].sym, (*results)[0].block); > - > - ndefns = remove_irrelevant_renamings (*results, ndefns, block0); > + cache_symbol (name, domain, (*results)[0].sym, (*results)[0].block); > > + ndefns = remove_irrelevant_renamings (*results, ndefns, block); > return ndefns; > } > > @@ -6036,6 +6126,11 @@ ada_add_block_symbols (struct obstack *obstackp, > } > } > > + /* Handle renamings. */ > + > + if (ada_add_block_renamings (obstackp, block, name, domain, wild)) > + found_sym = 1; > + > if (!found_sym && arg_sym != NULL) > { > add_defn_to_vec (obstackp, > diff --git a/gdb/buildsym.c b/gdb/buildsym.c > index 2a24a25..ac9c447 100644 > --- a/gdb/buildsym.c > +++ b/gdb/buildsym.c > @@ -503,8 +503,15 @@ finish_block_internal (struct symbol *symbol, struct pending **listhead, > opblock = pblock; > } > > - block_set_using (block, using_directives, &objfile->objfile_obstack); > - using_directives = NULL; > + block_set_using (block, > + is_global > + ? global_using_directives > + : local_using_directives, > + &objfile->objfile_obstack); > + if (is_global) > + global_using_directives = NULL; > + else > + local_using_directives = NULL; > > record_pending_block (objfile, block, opblock); > > @@ -1018,6 +1025,7 @@ prepare_for_building (const char *name, CORE_ADDR start_addr) > a symtab, or by the really_free_pendings cleanup. */ > gdb_assert (file_symbols == NULL); > gdb_assert (global_symbols == NULL); > + gdb_assert (global_using_directives == NULL); ==== I've put a lot of time into cleaning up buildsym.[ch] but we still have a long way to go (for at least a few reasons). I don't have a strong preference, but prepare_for_building should do *something* with local_using_directives. I think it doesn't because I was making so many changes I punted on this part. What's there now leaves one wondering (e.g., why does buildsym_init initialize local_using_directives? and why doesn't reset_symtab_globals reset local_using_directives? and there are more.). But I'm happy with leaving this for later, I just wanted to point out the issue. > gdb_assert (pending_macros == NULL); > gdb_assert (pending_addrmap == NULL); > gdb_assert (current_subfile == NULL); > @@ -1179,6 +1187,7 @@ reset_symtab_globals (void) > local_symbols = NULL; > file_symbols = NULL; > global_symbols = NULL; > + global_using_directives = NULL; > > /* We don't free pending_macros here because if the symtab was successfully > built then ownership was transferred to the symtab. */ > @@ -1281,7 +1290,8 @@ end_symtab_get_static_block (CORE_ADDR end_addr, int expandable, int required) > && file_symbols == NULL > && global_symbols == NULL > && have_line_numbers == 0 > - && pending_macros == NULL) > + && pending_macros == NULL > + && global_using_directives == NULL) > { > /* Ignore symtabs that have no functions with real debugging info. */ > return NULL; > @@ -1637,11 +1647,11 @@ push_context (int desc, CORE_ADDR valu) > newobj->locals = local_symbols; > newobj->old_blocks = pending_blocks; > newobj->start_addr = valu; > - newobj->using_directives = using_directives; > + newobj->local_using_directives = local_using_directives; > newobj->name = NULL; > > local_symbols = NULL; > - using_directives = NULL; > + local_using_directives = NULL; > > return newobj; > } > @@ -1740,7 +1750,7 @@ get_last_source_file (void) > void > buildsym_init (void) > { > - using_directives = NULL; > + local_using_directives = NULL; > subfile_stack = NULL; > > pending_addrmap_interesting = 0; > @@ -1760,6 +1770,7 @@ buildsym_init (void) > gdb_assert (pending_blocks == NULL); > gdb_assert (file_symbols == NULL); > gdb_assert (global_symbols == NULL); > + gdb_assert (global_using_directives == NULL); > gdb_assert (pending_macros == NULL); > gdb_assert (pending_addrmap == NULL); > gdb_assert (buildsym_compunit == NULL); > diff --git a/gdb/buildsym.h b/gdb/buildsym.h > index f98203e..4c0ec15 100644 > --- a/gdb/buildsym.h > +++ b/gdb/buildsym.h > @@ -118,7 +118,11 @@ EXTERN struct pending *local_symbols; > > /* "using" directives local to lexical context. */ > > -EXTERN struct using_direct *using_directives; > +EXTERN struct using_direct *local_using_directives; > + > +/* global "using" directives. */ > + > +EXTERN struct using_direct *global_using_directives; > > /* Stack representing unclosed lexical contexts (that will become > blocks, eventually). */ > @@ -131,7 +135,7 @@ struct context_stack > > /* Pending using directives at the time we entered. */ > > - struct using_direct *using_directives; > + struct using_direct *local_using_directives; > > /* Pointer into blocklist as of entry */ > > diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c > index 41f8d35..821ea9a 100644 > --- a/gdb/cp-namespace.c > +++ b/gdb/cp-namespace.c > @@ -91,7 +91,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol, > anonymous namespace. So add symbols in it to the > namespace given by the previous component if there is > one, or to the global namespace if there isn't. */ > - cp_add_using_directive (dest, src, NULL, NULL, NULL, 1, > + cp_add_using_directive (&local_using_directives, > + dest, src, NULL, NULL, NULL, 1, > &objfile->objfile_obstack); > } > /* The "+ 2" is for the "::". */ > @@ -103,7 +104,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol, > } > } > > -/* Add a using directive to using_directives. If the using directive > +/* Add a using directive to USING_DIRECTIVES. If the using directive > in question has already been added, don't add it twice. > > Create a new struct using_direct which imports the namespace SRC > @@ -118,7 +119,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol, > pointed to characters are not copied. */ > > void > -cp_add_using_directive (const char *dest, > +cp_add_using_directive (struct using_direct **using_directives, > + const char *dest, > const char *src, > const char *alias, > const char *declaration, > @@ -131,7 +133,7 @@ cp_add_using_directive (const char *dest, > > /* Has it already been added? */ > > - for (current = using_directives; current != NULL; current = current->next) > + for (current = *using_directives; current != NULL; current = current->next) > { > int ix; > const char *param; > @@ -195,8 +197,8 @@ cp_add_using_directive (const char *dest, > VEC_length (const_char_ptr, excludes) * sizeof (*newobj->excludes)); > newobj->excludes[VEC_length (const_char_ptr, excludes)] = NULL; > > - newobj->next = using_directives; > - using_directives = newobj; > + newobj->next = *using_directives; > + *using_directives = newobj; > } > > /* Test whether or not NAMESPACE looks like it mentions an anonymous > diff --git a/gdb/cp-support.h b/gdb/cp-support.h > index e92d6e7..72e7aa5 100644 > --- a/gdb/cp-support.h > +++ b/gdb/cp-support.h > @@ -181,7 +181,8 @@ extern struct type *cp_lookup_rtti_type (const char *name, > > extern int cp_is_in_anonymous (const char *symbol_name); > > -extern void cp_add_using_directive (const char *dest, > +extern void cp_add_using_directive (struct using_direct **using_directives, > + const char *dest, > const char *src, > const char *alias, > const char *declaration, > diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c > index f440956..370f66b 100644 > --- a/gdb/dwarf2read.c > +++ b/gdb/dwarf2read.c > @@ -8875,6 +8875,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) > const char *import_prefix; > VEC (const_char_ptr) *excludes = NULL; > struct cleanup *cleanups; > + struct using_direct **using_directives; > > import_attr = dwarf2_attr (die, DW_AT_import, cu); > if (import_attr == NULL) > @@ -8994,10 +8995,20 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) > process_die (child_die, cu); > } > > - cp_add_using_directive (import_prefix, > - canonical_name, > - import_alias, > - imported_declaration, > + /* For Ada, imported declarations can materialize renamings, which *may* be > + global. However it is impossible (for now?) in DWARF to distinguish > + "external" imported declarations and "static" ones. As all imported > + declarations seem to be static in all other languages, make them all > + CU-wide global only in Ada. */ > + if (cu->language == language_ada && context_stack_depth == 0) > + using_directives = &global_using_directives; > + else > + using_directives = &local_using_directives; > + cp_add_using_directive (using_directives, > + import_prefix, > + canonical_name, > + import_alias, > + imported_declaration, > excludes, > 0, > &objfile->objfile_obstack); > @@ -11480,7 +11491,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) > when we finish processing a function scope, we may need to go > back to building a containing block's symbol lists. */ > local_symbols = newobj->locals; > - using_directives = newobj->using_directives; > + local_using_directives = newobj->local_using_directives; > > /* If we've finished processing a top-level function, subsequent > symbols go in the file symbol list. */ > @@ -11526,7 +11537,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) > inherit_abstract_dies (die, cu); > newobj = pop_context (); > > - if (local_symbols != NULL || using_directives != NULL) > + if (local_symbols != NULL || local_using_directives != NULL) > { > struct block *block > = finish_block (0, &local_symbols, newobj->old_blocks, > @@ -11545,7 +11556,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) > dwarf2_record_block_ranges (die, block, baseaddr, cu); > } > local_symbols = newobj->locals; > - using_directives = newobj->using_directives; > + local_using_directives = newobj->local_using_directives; > } > > /* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */ > @@ -14094,7 +14105,10 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) > { > const char *previous_prefix = determine_prefix (die, cu); > > - cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, > + cp_add_using_directive ((context_stack_depth > 0) > + ? &local_using_directives > + : &global_using_directives, ==== Indentation is wrong. Typically what we do is surround the entire argument in () and indent like so: (foo > 0 ? bar : baz), Plus this needs a language_ada check (right?). > + previous_prefix, TYPE_NAME (type), NULL, > NULL, NULL, 0, &objfile->objfile_obstack); > } > } > diff --git a/gdb/testsuite/gdb.ada/fun_renaming.exp b/gdb/testsuite/gdb.ada/fun_renaming.exp > new file mode 100644 > index 0000000..fa76171 > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/fun_renaming.exp > @@ -0,0 +1,83 @@ > +# Copyright 2015 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 . > + > +load_lib "ada.exp" > + > +standard_ada_testfile fun_renaming > + > +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } { > + return -1 > +} > + > +clean_restart ${testfile} > + > +set bp_location [gdb_get_line_number "BREAK" ${testdir}/fun_renaming.adb] > +runto "fun_renaming.adb:$bp_location" > + > +# Sanity check: make sure we can call a regular global function. > +gdb_test "print next(1)" " = 2" > + > +# Starting with GCC 6, renamed subprograms are materialized in the debugging > +# information: make sure we can call the regular global function using its > +# multiple names. > + > +set test "print n(1)" > +gdb_test_multiple $test $test { > + -re " = 2\..*$gdb_prompt $" { > + pass $test > + } > + -re "No definition of \"n\" in current context\..*$gdb_prompt $" { > + if {[test_compiler_info {gcc-6*}]} { > + fail $test > + } else { > + xfail $test > + } > + } > + > +} > +set test "print renamed_next(1)" > +gdb_test_multiple $test $test { > + -re " = 2\..*$gdb_prompt $" { > + pass $test > + } > + -re "No definition of \"renamed_next\" in current context\..*$gdb_prompt $" { > + if {[test_compiler_info {gcc-6*}]} { > + fail $test > + } else { > + xfail $test > + } > + } > +} > + > +set test "print pack.renamed_next(1)" > +gdb_test_multiple $test $test { > + -re " = 2\..*$gdb_prompt $" { > + pass $test > + } > + -re "No definition of \"pack\.renamed_next\" in current context\..*$gdb_prompt $" { > + if {[test_compiler_info {gcc-6*}]} { > + fail $test > + } else { > + xfail $test > + } > + } > + -re "Type is not a structure or union type\..*$gdb_prompt $" { > + if {[test_compiler_info {gcc-6*}]} { > + fail $test > + } else { > + xfail $test > + } > + } > +} > diff --git a/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb b/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb > new file mode 100644 > index 0000000..c933585 > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb > @@ -0,0 +1,23 @@ > +-- Copyright 2015 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 . > + > +with Pack; > + > +procedure Fun_Renaming is > + function N (I : Integer) return Integer renames Pack.Next; > +begin > + Pack.Discard (N (1)); -- BREAK > + Pack.Discard (Pack.Renamed_Next (1)); -- BREAK > +end Fun_Renaming; > diff --git a/gdb/testsuite/gdb.ada/fun_renaming/pack.adb b/gdb/testsuite/gdb.ada/fun_renaming/pack.adb > new file mode 100644 > index 0000000..bdcd432 > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/fun_renaming/pack.adb > @@ -0,0 +1,26 @@ > +-- Copyright 2015 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 . > + > +package body Pack is > + function Next (I : Integer) return Integer is > + begin > + return I + 1; > + end Next; > + > + procedure Discard (I : Integer) is > + begin > + null; > + end Discard; > +end Pack; > diff --git a/gdb/testsuite/gdb.ada/fun_renaming/pack.ads b/gdb/testsuite/gdb.ada/fun_renaming/pack.ads > new file mode 100644 > index 0000000..2cf722c > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/fun_renaming/pack.ads > @@ -0,0 +1,22 @@ > +-- Copyright 2015 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 . > + > +package Pack is > + > + function Next (I : Integer) return Integer; > + function Renamed_Next (I : Integer) return Integer renames Next; > + procedure Discard (I : Integer); > + > +end Pack;