This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 1/2] namespace support
- From: Sami Wagiaalla <swagiaal at redhat dot com>
- To: tromey at redhat dot com
- Cc: GDB Patches <gdb-patches at sourceware dot org>
- Date: Fri, 19 Jun 2009 15:41:53 -0400
- Subject: Re: [PATCH 1/2] namespace support
- References: <4A16BAB5.80602@redhat.com> <m3y6s7v83b.fsf@fleche.redhat.com>
Tom Tromey wrote:
"Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:
Sami> Currently imports statements are stored in the nearest static
Sami> block. Also, these import statements only correspond to the
Sami> implicit importing of annonymous namespaces.
This looks pretty reasonable to me.
A few nits and such...
Sami> +/* This returns the using directives list associated to BLOCK, if
Sami> + any. Each BLOCK_NAMESPACE()->USING already contains all the namespaces
Sami> + imported at that code point - even those from its parent blocks. */
I think the caps on "USING" here are weird.
Maybe just:
The result contains all the [...]
I changed it to:
/* This returns the using directives list associated with BLOCK, if
any. */
The second part of the comment is not correct.
Sami> +/* using directives local to lexical context */
Comments should in general be sentences -- starting with a capital
letter and ending with a period and two spaces.
Here I would probably write:
/* "using" directives local to lexical context. */
... avoiding the capital since "using" is a keyword.
Sami> +EXTERN struct using_direct *using_directives;
Eww, buildsym is full of globals. Not your problem :-), but yet
another thing that would be nice to clean up.
There is a nice clean up for this suggested by Jan. That is using the
variables in the current context object and automating saving/and
restoration of that. I'll post a patch if I get to it.
Sami> +static void
Sami> +read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
[...]
Sami> + if (imported_name == NULL)
Sami> + {
Sami> + /* C++ imports from std:: DW_TAG_base_type with no DW_AT_name - why? */
It would be nice to understand this before the patch goes in.
This is a gcc bug. I filed it here:
https://bugzilla.redhat.com/show_bug.cgi?id=506524 and improved the comment.
and improved the comment.
also I changed the line above the comment to use dwarf2_name instead of
namespace_name which is incorrect.
- imported_name = namespace_name (imported_die, &is_anonymous, cu);
+ imported_name = dwarf2_name (imported_die, cu);
Sami> + /* FIXME: dwarf2_name (die); for the local name after import. */
It would also be nice if we could not add new FIXMEs.
Or is that handled in a later patch?
Yes, it will be handled in a later patch.
Sami> + using_directives = cp_add_using (imported_name, strlen (imported_name), 0,
Sami> + using_directives);
Sami> +}
I didn't look -- but are there other buildsym globals which are
actively updated by the dwarf reader like this? I'm wondering whether
this is something that should be hidden inside a call, like a new
wrapper for cp_add_using.
For now using_directives is a global. I wrote this to be parallel to
local_symbols. If the context clean up is done cp_add_using can just
request the current context
This is not a big deal.
Tom
-----------------------------------------
2009-05-21 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.
diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..9ebe975 100644
--- a/gdb/block.c
+++ b/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
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index e7c48fe..e6ef9c6 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -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). */
@@ -1012,8 +1010,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. */
@@ -1225,10 +1221,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;
}
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
index bf23ecc..6f8b09f 100644
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -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;
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index c6c5617..f3b2194 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -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,
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 837ca6c..e577f7d 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -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,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ae8870c..6569798 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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 *);
@@ -2984,14 +2986,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);
@@ -3037,6 +3037,69 @@ 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;
+ int is_anonymous = 0;
+
+ 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)
{
@@ -3370,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. */
@@ -3432,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.
2009-05-21 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.
diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..9ebe975 100644
--- a/gdb/block.c
+++ b/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
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index e7c48fe..e6ef9c6 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -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). */
@@ -1012,8 +1010,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. */
@@ -1225,10 +1221,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;
}
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
index bf23ecc..6f8b09f 100644
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -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;
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index c6c5617..f3b2194 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -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,
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 837ca6c..e577f7d 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -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,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ae8870c..6569798 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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 *);
@@ -2984,14 +2986,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);
@@ -3037,6 +3037,69 @@ 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;
+ int is_anonymous = 0;
+
+ 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)
{
@@ -3370,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. */
@@ -3432,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.