2009-06-23 Sami Wagiaalla <swagiaal@redhat.com>
* dwarf2read.c (process_die): Handle import statements (DW_TAG_imported_declaration, case DW_TAG_imported_module) (read_import_statement): New. (read_func_scope): Update using_directives to point to current context (read_lexical_block_scope): Ditto. * cp-support.h: Added prototype for cp_add_using. * cp-namespace.c: Removed local context_stack. (cp_initialize_namespace): Deleted. (cp_finalize_namespace): Deleted. (cp_add_using_directive): Use using_directives instead of using_list. (cp_add_using): No longer static. * buildsym.h: Created global using_direct variable. Created using_direct variable in context_stack. * buildsym.c (finish_block): Set using directives for the block under construction. (start_symtab): Removed call to cp_initialize_namespace(). (end_symtab): Removed call to cp_finalize_namespace(). (push_context): Save and reset using_directives. * block.c (block_using): Return using directives for given block instead of static block. 2009-06-23 Sami Wagiaalla <swagiaal@redhat.com> * gdb.cp/namespace-using.exp: New test. * gdb.cp/namespace-using.cc: New test.
This commit is contained in:
parent
ad068eabda
commit
27aa8d6aa0
|
@ -1,3 +1,26 @@
|
|||
2009-06-23 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* dwarf2read.c (process_die): Handle import statements
|
||||
(DW_TAG_imported_declaration, case DW_TAG_imported_module)
|
||||
(read_import_statement): New.
|
||||
(read_func_scope): Update using_directives to point to current context
|
||||
(read_lexical_block_scope): Ditto.
|
||||
* cp-support.h: Added prototype for cp_add_using.
|
||||
* cp-namespace.c: Removed local context_stack.
|
||||
(cp_initialize_namespace): Deleted.
|
||||
(cp_finalize_namespace): Deleted.
|
||||
(cp_add_using_directive): Use using_directives instead of using_list.
|
||||
(cp_add_using): No longer static.
|
||||
* buildsym.h: Created global using_direct variable.
|
||||
Created using_direct variable in context_stack.
|
||||
* buildsym.c (finish_block): Set using directives for the block under
|
||||
construction.
|
||||
(start_symtab): Removed call to cp_initialize_namespace().
|
||||
(end_symtab): Removed call to cp_finalize_namespace().
|
||||
(push_context): Save and reset using_directives.
|
||||
* block.c (block_using): Return using directives for given
|
||||
block instead of static block.
|
||||
|
||||
2009-06-23 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* target-descriptions.h (struct type): Do not declare.
|
||||
|
|
15
gdb/block.c
15
gdb/block.c
|
@ -206,25 +206,16 @@ block_set_scope (struct block *block, const char *scope,
|
|||
BLOCK_NAMESPACE (block)->scope = scope;
|
||||
}
|
||||
|
||||
/* This returns the first using directives associated to BLOCK, if
|
||||
/* This returns the using directives list associated with BLOCK, if
|
||||
any. */
|
||||
|
||||
/* FIXME: carlton/2003-04-23: This uses the fact that we currently
|
||||
only have using directives in static blocks, because we only
|
||||
generate using directives from anonymous namespaces. Eventually,
|
||||
when we support using directives everywhere, we'll want to replace
|
||||
this by some iterator functions. */
|
||||
|
||||
struct using_direct *
|
||||
block_using (const struct block *block)
|
||||
{
|
||||
const struct block *static_block = block_static_block (block);
|
||||
|
||||
if (static_block == NULL
|
||||
|| BLOCK_NAMESPACE (static_block) == NULL)
|
||||
if (block == NULL || BLOCK_NAMESPACE (block) == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return BLOCK_NAMESPACE (static_block)->using;
|
||||
return BLOCK_NAMESPACE (block)->using;
|
||||
}
|
||||
|
||||
/* Set BLOCK's using member to USING; if needed, allocate memory via
|
||||
|
|
|
@ -384,6 +384,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
|
|||
opblock = pblock;
|
||||
}
|
||||
|
||||
block_set_using (block, using_directives, &objfile->objfile_obstack);
|
||||
|
||||
record_pending_block (objfile, block, opblock);
|
||||
|
||||
return block;
|
||||
|
@ -812,10 +814,6 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
|
|||
/* We shouldn't have any address map at this point. */
|
||||
gdb_assert (! pending_addrmap);
|
||||
|
||||
/* Set up support for C++ namespace support, in case we need it. */
|
||||
|
||||
cp_initialize_namespace ();
|
||||
|
||||
/* Initialize the list of sub source files with one entry for this
|
||||
file (the top-level source file). */
|
||||
|
||||
|
@ -1021,8 +1019,6 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
|
|||
finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
|
||||
objfile);
|
||||
blockvector = make_blockvector (objfile);
|
||||
cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
|
||||
&objfile->objfile_obstack);
|
||||
}
|
||||
|
||||
/* Read the line table if it has to be read separately. */
|
||||
|
@ -1234,10 +1230,12 @@ push_context (int desc, CORE_ADDR valu)
|
|||
new->params = param_symbols;
|
||||
new->old_blocks = pending_blocks;
|
||||
new->start_addr = valu;
|
||||
new->using_directives = using_directives;
|
||||
new->name = NULL;
|
||||
|
||||
local_symbols = NULL;
|
||||
param_symbols = NULL;
|
||||
using_directives = NULL;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,10 @@ EXTERN struct pending *local_symbols;
|
|||
|
||||
EXTERN struct pending *param_symbols;
|
||||
|
||||
/* "using" directives local to lexical context. */
|
||||
|
||||
EXTERN struct using_direct *using_directives;
|
||||
|
||||
/* Stack representing unclosed lexical contexts (that will become
|
||||
blocks, eventually). */
|
||||
|
||||
|
@ -138,6 +142,10 @@ struct context_stack
|
|||
|
||||
struct pending *params;
|
||||
|
||||
/* Pending using directives at the time we entered. */
|
||||
|
||||
struct using_direct *using_directives;
|
||||
|
||||
/* Pointer into blocklist as of entry */
|
||||
|
||||
struct pending_block *old_blocks;
|
||||
|
|
|
@ -30,15 +30,7 @@
|
|||
#include "dictionary.h"
|
||||
#include "command.h"
|
||||
#include "frame.h"
|
||||
|
||||
/* List of using directives that are active in the current file. */
|
||||
|
||||
static struct using_direct *using_list;
|
||||
|
||||
static struct using_direct *cp_add_using (const char *name,
|
||||
unsigned int inner_len,
|
||||
unsigned int outer_len,
|
||||
struct using_direct *next);
|
||||
#include "buildsym.h"
|
||||
|
||||
static struct using_direct *cp_copy_usings (struct using_direct *using,
|
||||
struct obstack *obstack);
|
||||
|
@ -78,31 +70,6 @@ static struct symbol *lookup_possible_namespace_symbol (const char *name);
|
|||
|
||||
static void maintenance_cplus_namespace (char *args, int from_tty);
|
||||
|
||||
/* Set up support for dealing with C++ namespace info in the current
|
||||
symtab. */
|
||||
|
||||
void cp_initialize_namespace ()
|
||||
{
|
||||
using_list = NULL;
|
||||
}
|
||||
|
||||
/* Add all the using directives we've gathered to the current symtab.
|
||||
STATIC_BLOCK should be the symtab's static block; OBSTACK is used
|
||||
for allocation. */
|
||||
|
||||
void
|
||||
cp_finalize_namespace (struct block *static_block,
|
||||
struct obstack *obstack)
|
||||
{
|
||||
if (using_list != NULL)
|
||||
{
|
||||
block_set_using (static_block,
|
||||
cp_copy_usings (using_list, obstack),
|
||||
obstack);
|
||||
using_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if SYMBOL refers to an object contained within an
|
||||
anonymous namespace; if so, add an appropriate using directive. */
|
||||
|
||||
|
@ -170,7 +137,7 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
|
|||
|
||||
/* Has it already been added? */
|
||||
|
||||
for (current = using_list; current != NULL; current = current->next)
|
||||
for (current = using_directives; current != NULL; current = current->next)
|
||||
{
|
||||
if ((strncmp (current->inner, name, inner_length) == 0)
|
||||
&& (strlen (current->inner) == inner_length)
|
||||
|
@ -178,8 +145,8 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
|
|||
return;
|
||||
}
|
||||
|
||||
using_list = cp_add_using (name, inner_length, outer_length,
|
||||
using_list);
|
||||
using_directives = cp_add_using (name, inner_length, outer_length,
|
||||
using_directives);
|
||||
}
|
||||
|
||||
/* Record the namespace that the function defined by SYMBOL was
|
||||
|
@ -237,7 +204,7 @@ cp_is_anonymous (const char *namespace)
|
|||
using xmalloc. It copies the strings, so NAME can be a temporary
|
||||
string. */
|
||||
|
||||
static struct using_direct *
|
||||
struct using_direct *
|
||||
cp_add_using (const char *name,
|
||||
unsigned int inner_len,
|
||||
unsigned int outer_len,
|
||||
|
|
|
@ -80,6 +80,11 @@ extern void cp_add_using_directive (const char *name,
|
|||
unsigned int outer_length,
|
||||
unsigned int inner_length);
|
||||
|
||||
extern struct using_direct *cp_add_using (const char *name,
|
||||
unsigned int inner_len,
|
||||
unsigned int outer_len,
|
||||
struct using_direct *next);
|
||||
|
||||
extern void cp_initialize_namespace (void);
|
||||
|
||||
extern void cp_finalize_namespace (struct block *static_block,
|
||||
|
|
|
@ -946,6 +946,8 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *);
|
|||
|
||||
static void read_module (struct die_info *die, struct dwarf2_cu *cu);
|
||||
|
||||
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
|
||||
|
||||
static const char *namespace_name (struct die_info *die,
|
||||
int *is_anonymous, struct dwarf2_cu *);
|
||||
|
||||
|
@ -2985,14 +2987,12 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
|
|||
break;
|
||||
case DW_TAG_imported_declaration:
|
||||
case DW_TAG_imported_module:
|
||||
/* FIXME: carlton/2002-10-16: Eventually, we should use the
|
||||
information contained in these. DW_TAG_imported_declaration
|
||||
dies shouldn't have children; DW_TAG_imported_module dies
|
||||
shouldn't in the C++ case, but conceivably could in the
|
||||
Fortran case. */
|
||||
processing_has_namespace_info = 1;
|
||||
complaint (&symfile_complaints, _("unsupported tag: '%s'"),
|
||||
dwarf_tag_name (die->tag));
|
||||
if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
|
||||
|| cu->language != language_fortran))
|
||||
complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
|
||||
dwarf_tag_name (die->tag));
|
||||
read_import_statement (die, cu);
|
||||
break;
|
||||
default:
|
||||
new_symbol (die, NULL, cu);
|
||||
|
@ -3038,6 +3038,68 @@ dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
|
|||
return name;
|
||||
}
|
||||
|
||||
/* Read the import statement specified by the given die and record it. */
|
||||
|
||||
static void
|
||||
read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
|
||||
{
|
||||
struct attribute *import_attr;
|
||||
struct die_info *imported_die;
|
||||
const char *imported_name;
|
||||
|
||||
import_attr = dwarf2_attr (die, DW_AT_import, cu);
|
||||
if (import_attr == NULL)
|
||||
{
|
||||
complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
|
||||
dwarf_tag_name (die->tag));
|
||||
return;
|
||||
}
|
||||
|
||||
imported_die = follow_die_ref (die, import_attr, &cu);
|
||||
imported_name = dwarf2_name (imported_die, cu);
|
||||
if (imported_name == NULL)
|
||||
{
|
||||
/* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
|
||||
|
||||
The import in the following code:
|
||||
namespace A
|
||||
{
|
||||
typedef int B;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
using A::B;
|
||||
B b;
|
||||
return b;
|
||||
}
|
||||
|
||||
...
|
||||
<2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
|
||||
<52> DW_AT_decl_file : 1
|
||||
<53> DW_AT_decl_line : 6
|
||||
<54> DW_AT_import : <0x75>
|
||||
<2><58>: Abbrev Number: 4 (DW_TAG_typedef)
|
||||
<59> DW_AT_name : B
|
||||
<5b> DW_AT_decl_file : 1
|
||||
<5c> DW_AT_decl_line : 2
|
||||
<5d> DW_AT_type : <0x6e>
|
||||
...
|
||||
<1><75>: Abbrev Number: 7 (DW_TAG_base_type)
|
||||
<76> DW_AT_byte_size : 4
|
||||
<77> DW_AT_encoding : 5 (signed)
|
||||
|
||||
imports the wrong die ( 0x75 instead of 0x58 ).
|
||||
This case will be ignored until the gcc bug is fixed. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: dwarf2_name (die); for the local name after import. */
|
||||
|
||||
using_directives = cp_add_using (imported_name, strlen (imported_name), 0,
|
||||
using_directives);
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_cu_func_list (struct dwarf2_cu *cu)
|
||||
{
|
||||
|
@ -3371,6 +3433,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||
back to building a containing block's symbol lists. */
|
||||
local_symbols = new->locals;
|
||||
param_symbols = new->params;
|
||||
using_directives = new->using_directives;
|
||||
|
||||
/* If we've finished processing a top-level function, subsequent
|
||||
symbols go in the file symbol list. */
|
||||
|
@ -3433,6 +3496,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||
dwarf2_record_block_ranges (die, block, baseaddr, cu);
|
||||
}
|
||||
local_symbols = new->locals;
|
||||
using_directives = new->using_directives;
|
||||
}
|
||||
|
||||
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-06-23 Sami Wagiaalla <swagiaal@redhat.com>
|
||||
|
||||
* gdb.cp/namespace-using.exp: New test.
|
||||
* gdb.cp/namespace-using.cc: New test.
|
||||
|
||||
2009-05-20 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.ada/variant_record_packed_array: New testcase.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
namespace A
|
||||
{
|
||||
int _a = 1;
|
||||
int x = 2;
|
||||
}
|
||||
|
||||
int marker4(){
|
||||
using A::x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int marker3(){
|
||||
return marker4();
|
||||
}
|
||||
|
||||
int marker2()
|
||||
{
|
||||
namespace B = A;
|
||||
B::_a;
|
||||
return marker3();
|
||||
}
|
||||
|
||||
int marker1()
|
||||
{
|
||||
int total = 0;
|
||||
{
|
||||
int b = 1;
|
||||
{
|
||||
using namespace A;
|
||||
int c = 2;
|
||||
{
|
||||
int d = 3;
|
||||
total = _a + b + c + d + marker2(); // marker1 stop
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace A;
|
||||
_a;
|
||||
return marker1();
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
# Copyright 2008 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/>.
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile namespace-using
|
||||
set srcfile ${testfile}.cc
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
|
||||
untested "Couldn't compile test program"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Get things started.
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
############################################
|
||||
# test printing of namespace imported within
|
||||
# the function.
|
||||
|
||||
if ![runto_main] then {
|
||||
perror "couldn't run to breakpoint main"
|
||||
continue
|
||||
}
|
||||
|
||||
gdb_test "print _a" "= 1"
|
||||
|
||||
############################################
|
||||
# test printing of namespace imported into
|
||||
# a scope containing the pc.
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "marker1 stop"]
|
||||
gdb_continue_to_breakpoint "marker1 stop"
|
||||
|
||||
gdb_test "print _a" "= 1" "print _a in a nested scope"
|
||||
|
||||
############################################
|
||||
# Test printing of namespace aliases
|
||||
|
||||
setup_kfail "gdb/7935" "*-*-*"
|
||||
if ![runto marker2] then {
|
||||
perror "couldn't run to breakpoint marker2"
|
||||
continue
|
||||
}
|
||||
|
||||
gdb_test "print B::a" "= 1"
|
||||
|
||||
############################################
|
||||
# Test that names are not printed when they
|
||||
# are not imported
|
||||
|
||||
gdb_breakpoint "marker3"
|
||||
gdb_continue_to_breakpoint "marker3"
|
||||
|
||||
gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import"
|
||||
|
||||
############################################
|
||||
# Test printing of individually imported elements
|
||||
|
||||
setup_kfail "gdb/7936" "*-*-*"
|
||||
if ![runto marker4] then {
|
||||
perror "couldn't run to breakpoint marker4"
|
||||
continue
|
||||
}
|
||||
|
||||
gdb_test "print x" "= 2"
|
Loading…
Reference in New Issue