aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2003-09-30 18:16:07 +0000
committerDavid Carlton <carlton@bactrian.org>2003-09-30 18:16:07 +0000
commitbf5543d0ac6881c97433a44aea21c10b91b70701 (patch)
treec23754bee9b842eae3e4b1b05783149ac7490d4d
parentc6c437768c9525852e08705f143181109b9af7e5 (diff)
downloadgdb-bf5543d0ac6881c97433a44aea21c10b91b70701.zip
gdb-bf5543d0ac6881c97433a44aea21c10b91b70701.tar.gz
gdb-bf5543d0ac6881c97433a44aea21c10b91b70701.tar.bz2
2003-09-30 David Carlton <carlton@kealia.com>
* Makefile.in (c-exp.tab.o): Depend on cp_support_h. * c-exp.y: Include c-exp.y. Update comments, replace lookup_nested_type by cp_lookup_nested_type. (yylex): Update comments, remove #if 0 block. * cp-namespace.c (cp_lookup_nested_type): Move here from symtab.c; rename from lookup_nested_type. * cp-support.h: Add cp_lookup_nested_type declaration. * dwarf2read.c (read_die_and_children): Update comment. (read_die_and_siblings): Update comment, move declaration of 'die'. (read_full_die): Update comment, tweak formatting. * symtab.c (lookup_nested_type): Move to cp-namespace.c, rename to cp_lookup_nested_type. * symtab.h: Delete declaration of lookup_nested_type.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/c-exp.y154
-rw-r--r--gdb/cp-namespace.c45
-rw-r--r--gdb/cp-support.h4
-rw-r--r--gdb/dwarf2read.c27
-rw-r--r--gdb/symtab.c47
-rw-r--r--gdb/symtab.h6
8 files changed, 139 insertions, 163 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6adec6f..15f7f1d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2003-09-30 David Carlton <carlton@kealia.com>
+
+ * Makefile.in (c-exp.tab.o): Depend on cp_support_h.
+ * c-exp.y: Include c-exp.y. Update comments, replace
+ lookup_nested_type by cp_lookup_nested_type.
+ (yylex): Update comments, remove #if 0 block.
+ * cp-namespace.c (cp_lookup_nested_type): Move here from symtab.c;
+ rename from lookup_nested_type.
+ * cp-support.h: Add cp_lookup_nested_type declaration.
+ * dwarf2read.c (read_die_and_children): Update comment.
+ (read_die_and_siblings): Update comment, move declaration of
+ 'die'.
+ (read_full_die): Update comment, tweak formatting.
+ * symtab.c (lookup_nested_type): Move to cp-namespace.c, rename to
+ cp_lookup_nested_type.
+ * symtab.h: Delete declaration of lookup_nested_type.
+
2003-09-19 David Carlton <carlton@kealia.com>
* expression.h (enum exp_opcode): Revert to mainline's OP_FUNCALL,
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3bb61f7..270007e 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1412,7 +1412,7 @@ ada-lex.c: ada-lex.l
.PRECIOUS: c-exp.tab.c
c-exp.tab.o: c-exp.tab.c $(defs_h) $(gdb_string_h) $(expression_h) \
$(value_h) $(parser_defs_h) $(language_h) $(c_lang_h) $(bfd_h) \
- $(symfile_h) $(objfiles_h) $(charset_h) $(block_h)
+ $(symfile_h) $(objfiles_h) $(charset_h) $(block_h) $(cp_support_h)
c-exp.tab.c: c-exp.y
$(SHELL) $(YLWRAP) "$(YACC)" \
$(srcdir)/c-exp.y y.tab.c c-exp.tmp -- $(YFLAGS)
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 0372686..abe52d7 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -51,6 +51,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "charset.h"
#include "block.h"
+#include "cp-support.h"
/* Flag indicating we're dealing with HP-compiled objects */
extern int hp_som_som_object_present;
@@ -894,23 +895,50 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
| qualified_type
;
-/* FIXME: carlton/2003-09-19: This leads to lots of reduce-reduce
- conflicts, because the parser doesn't know whether or not to use
- qualified_name or qualified_type. There's no good way to fix this
- with the grammar as it stands; as far as I can tell, some of the
- problems arise from ambiguities that GDB introduces ('start' can be
- either an expression or a type), but some of it is inherent to the
- nature of C++ (you want to treat the input "(FOO)" fairly
- differently depending on whether FOO is an expression or a type,
- and if FOO is a complex expression, this can be hard to determine
- at the right time.
-
- Perhaps we could fix this by making the lexer smarter. (Some of
+/* FIXME: carlton/2003-09-25: This next bit leads to lots of
+ reduce-reduce conflicts, because the parser doesn't know whether or
+ not to use qualified_name or qualified_type: the rules are
+ identical. If the parser is parsing 'A::B::x', then, when it sees
+ the second '::', it knows that the expression to the left of it has
+ to be a type, so it uses qualified_type. But if it is parsing just
+ 'A::B', then it doesn't have any way of knowing which rule to use,
+ so there's a reduce-reduce conflict; it picks qualified_name, since
+ that occurs earlier in this file than qualified_type.
+
+ There's no good way to fix this with the grammar as it stands; as
+ far as I can tell, some of the problems arise from ambiguities that
+ GDB introduces ('start' can be either an expression or a type), but
+ some of it is inherent to the nature of C++ (you want to treat the
+ input "(FOO)" fairly differently depending on whether FOO is an
+ expression or a type, and if FOO is a complex expression, this can
+ be hard to determine at the right time). Fortunately, it works
+ pretty well in most cases. For example, if you do 'ptype A::B',
+ where A::B is a nested type, then the parser will mistakenly
+ misidentify it as an expression; but evaluate_subexp will get
+ called with 'noside' set to EVAL_AVOID_SIDE_EFFECTS, and everything
+ will work out anyways. But there are situations where the parser
+ will get confused: the most common one that I've run into is when
+ you want to do
+
+ print *((A::B *) x)"
+
+ where the parser doesn't realize that A::B has to be a type until
+ it hits the first right paren, at which point it's too late. (The
+ workaround is to type "print *(('A::B' *) x)" instead.) (And
+ another solution is to fix our symbol-handling code so that the
+ user never wants to type something like that in the first place,
+ because we get all the types right without the user's help!)
+
+ Perhaps we could fix this by making the lexer smarter. Some of
this functionality used to be in the lexer, but in a way that
- worked even less well than the current solution.) Ideally, the
- code in question could be shared by the lexer and by decode_line_1.
- I'm not holding my breath waiting for somebody to get around to
- cleaning this up, however... */
+ worked even less well than the current solution: that attempt
+ involved having the parser sometimes handle '::' and having the
+ lexer sometimes handle it, and without a clear division of
+ responsibility, it quickly degenerated into a big mess. Probably
+ the eventual correct solution will give more of a role to the lexer
+ (ideally via code that is shared between the lexer and
+ decode_line_1), but I'm not holding my breath waiting for somebody
+ to get around to cleaning this up... */
qualified_type: typebase COLONCOLON name
{
@@ -927,8 +955,8 @@ qualified_type: typebase COLONCOLON name
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- new_type = lookup_nested_type (type, ncopy,
- expression_context_block);
+ new_type = cp_lookup_nested_type (type, ncopy,
+ expression_context_block);
if (new_type == NULL)
error ("No type \"%s\" within class or namespace \"%s\".",
ncopy, TYPE_NAME (type));
@@ -1682,12 +1710,11 @@ yylex ()
HP aCC compiler's generation of symbol names with embedded
colons for namespace and nested classes. */
- /* NOTE: carlton/2002-12-17: I really don't understand this
- HP-specific stuff (here or in linespec), but it has to go away.
- It's actually possible that it would be best to start from the
- current HP case than from the current non-HP case: the
- description of HP symbol names sounds like what I'm trying to get
- symbol names to look like. */
+ /* NOTE: carlton/2003-09-24: I don't entirely understand the
+ HP-specific code, either here or in linespec. Having said that,
+ I suspect that we're actually moving towards their model: we want
+ symbols whose names are fully qualified, which matches the
+ description above. */
if (unquoted_expr)
{
/* Only do it if not inside single quotes */
@@ -1741,83 +1768,10 @@ yylex ()
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
-#if 0
- char *p;
- char *namestart;
- struct type *best_type;
-
- /* Look ahead to detect nested types. This probably should be
- done in the grammar, but trying seemed to introduce a lot
- of shift/reduce and reduce/reduce conflicts. It's possible
- that it could be done, though. Or perhaps a non-grammar, but
- less ad hoc, approach would work well. */
-
- /* NOTE: carlton/2002-12-17: The idea of doing this in the
- lexer rather than the grammar seems awful to me.
- Unfortunately, there currently seems to be no way around
- it that I can see: the grammar is for either expressions
- or types (see the 'start' rule), so it can be used for
- the commands 'print' and 'ptype', and furthermore it's
- the parser's job to evaluate types whereas it's
- evaluate_expression's job to evaluate other expressions,
- which combine to make an awful mess.
-
- So, for now, we 'handle' nested types here. Sigh. But I
- really don't think this setup is a good idea: it papers
- over :: issues, and should fall flat on its face when
- dealing with initial :: operators.
-
- An earlier version of this code was even worse: it
- 'dealt' with nested types by pretending they weren't
- nested, because of stabs limitations. Sigh. */
-
- p = lexptr;
- best_type = SYMBOL_TYPE (sym);
- while (1)
- {
- /* Skip whitespace. */
- while (*p == ' ' || *p == '\t' || *p == '\n')
- ++p;
- if (*p == ':' && p[1] == ':')
- {
- /* Skip the `::'. */
- p += 2;
- /* Skip whitespace. */
- while (*p == ' ' || *p == '\t' || *p == '\n')
- ++p;
- namestart = p;
- while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
- || (*p >= 'a' && *p <= 'z')
- || (*p >= 'A' && *p <= 'Z'))
- ++p;
- if (p != namestart)
- {
- struct type *cur_type;
- char *ncopy = alloca (p - namestart + 1);
- memcpy (ncopy, namestart, p - namestart);
- ncopy[p - namestart] = '\0';
- cur_type = lookup_nested_type (best_type,
- ncopy,
- expression_context_block);
- if (cur_type != NULL)
- {
- best_type = cur_type;
- lexptr = p;
- }
- else
- break;
- }
- else
- break;
- }
- else
- break;
- }
-
- yylval.tsym.type = best_type;
-#else /* not 1 */
+ /* NOTE: carlton/2003-09-25: There used to be code here to
+ handle nested types. It didn't work very well. See the
+ comment before qualified_type for more info. */
yylval.tsym.type = SYMBOL_TYPE (sym);
-#endif /* not 1 */
return TYPENAME;
}
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 226dab5..e48e9c3 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -520,6 +520,51 @@ lookup_symbol_file (const char *name,
return NULL;
}
+/* Look up a type named NESTED_NAME that is nested inside the C++
+ class or namespace given by PARENT_TYPE, from within the context
+ given by BLOCK. */
+
+struct type *
+cp_lookup_nested_type (struct type *parent_type,
+ const char *nested_name,
+ const struct block *block)
+{
+ switch (TYPE_CODE (parent_type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_NAMESPACE:
+ {
+ /* NOTE: carlton/2002-12-17: As of this writing, C++ class
+ members of classes aren't treated like, say, data or
+ function members. Instead, they're just represented by
+ symbols whose names are qualified by the name of the
+ surrounding class. This is just like members of
+ namespaces; in particular, lookup_symbol_namespace works
+ when looking them up. */
+
+ /* NOTE: carlton/2002-12-17: The above is, actually, lying:
+ there are still situations where nested types are
+ represented by symbols that include only the member name,
+ not the parent name. Sigh. Blame it on stabs, or
+ something. */
+ const char *parent_name = TYPE_TAG_NAME (parent_type);
+ struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
+ nested_name,
+ NULL,
+ block,
+ VAR_DOMAIN,
+ NULL);
+ if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ return NULL;
+ else
+ return SYMBOL_TYPE (sym);
+ }
+ default:
+ error ("\"%s\" is not defined as a compound type.",
+ TYPE_NAME (parent_type));
+ }
+}
+
/* Try to look up the type definition associated to NAME if honest
methods don't work: look for NAME in the classes/namespaces that
are currently active, on the off chance that it might be there. */
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 563ca37..a4edf0c 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -102,6 +102,10 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
const domain_enum domain,
struct symtab **symtab);
+extern struct type *cp_lookup_nested_type (struct type *parent_type,
+ const char *nested_name,
+ const struct block *block);
+
extern void cp_check_possible_namespace_symbols (const char *name,
struct objfile *objfile);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index e62fd90..bfd9031 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4023,7 +4023,11 @@ read_comp_unit (char *info_ptr, bfd *abfd,
return read_die_and_children (info_ptr, abfd, cu_header, &info_ptr, NULL);
}
-/* Read a single die and all its descendents. */
+/* Read a single die and all its descendents. Set the die's sibling
+ field to NULL; set other fields in the die correctly, and set all
+ of the descendents' fields correctly. Set *NEW_INFO_PTR to the
+ location of the info_ptr after reading all of those dies. PARENT
+ is the parent of the die in question. */
static struct die_info *
read_die_and_children (char *info_ptr, bfd *abfd,
@@ -4054,8 +4058,9 @@ read_die_and_children (char *info_ptr, bfd *abfd,
return die;
}
-/* Helper function for read_comp_unit; it reads in a die, all of its
- descendents, and all of its siblings. */
+/* Read a die, all of its descendents, and all of its siblings; set
+ all of the fields of all of the dies correctly. Arguments are as
+ in read_die_and_children. */
static struct die_info *
read_die_and_siblings (char *info_ptr, bfd *abfd,
@@ -4063,7 +4068,7 @@ read_die_and_siblings (char *info_ptr, bfd *abfd,
char **new_info_ptr,
struct die_info *parent)
{
- struct die_info *first_die, *last_sibling, *die;
+ struct die_info *first_die, *last_sibling;
char *cur_ptr;
cur_ptr = info_ptr;
@@ -4071,7 +4076,9 @@ read_die_and_siblings (char *info_ptr, bfd *abfd,
while (1)
{
- die = read_die_and_children (cur_ptr, abfd, cu_header, &cur_ptr, parent);
+ struct die_info *die
+ = read_die_and_children (cur_ptr, abfd, cu_header,
+ &cur_ptr, parent);
if (!first_die)
{
@@ -4421,8 +4428,9 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
}
/* Read the die from the .debug_info section buffer. Set DIEP to
- point to a newly allocated die with its information, and set
- HAS_CHILDREN to tell whether the die has children or not. */
+ point to a newly allocated die with its information, except for its
+ child, sibling, and parent fields. Set HAS_CHILDREN to tell
+ whether the die has children or not. */
static char *
read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
@@ -4449,8 +4457,9 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
if (!abbrev)
{
- error ("Dwarf Error: could not find abbrev number %d [in module %s]", abbrev_number,
- bfd_get_filename (abfd));
+ error ("Dwarf Error: could not find abbrev number %d [in module %s]",
+ abbrev_number,
+ bfd_get_filename (abfd));
}
die = dwarf_alloc_die ();
die->offset = offset;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3554be1..f739457 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1347,53 +1347,6 @@ lookup_symbol_linkage (const char *linkage_name)
return sym;
}
-/* Look up a type named NESTED_NAME that is nested inside the C++
- class or namespace given by PARENT_TYPE, from within the context
- given by BLOCK. */
-
-/* FIXME: Move to cp-namespace.c. */
-
-struct type *
-lookup_nested_type (struct type *parent_type,
- const char *nested_name,
- const struct block *block)
-{
- switch (TYPE_CODE (parent_type))
- {
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_NAMESPACE:
- {
- /* NOTE: carlton/2002-12-17: As of this writing, C++ class
- members of classes aren't treated like, say, data or
- function members. Instead, they're just represented by
- symbols whose names are qualified by the name of the
- surrounding class. This is just like members of
- namespaces; in particular, lookup_symbol_namespace works
- when looking them up. */
-
- /* NOTE: carlton/2002-12-17: The above is, actually, lying:
- there are still situations where nested types are
- represented by symbols that include only the member name,
- not the parent name. Sigh. Blame it on stabs, or
- something. */
- const char *parent_name = TYPE_TAG_NAME (parent_type);
- struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
- nested_name,
- NULL,
- block,
- VAR_DOMAIN,
- NULL);
- if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
- return NULL;
- else
- return SYMBOL_TYPE (sym);
- }
- default:
- error ("\"%s\" is not defined as a compound type.",
- TYPE_NAME (parent_type));
- }
-}
-
/* A default version of lookup_symbol_nonlocal for use by languages
that can't think of anything better to do. This implements the C
lookup rules. */
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 54d9731..f288e94 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1024,12 +1024,6 @@ extern struct symbol *lookup_symbol_minsym (const struct minimal_symbol
extern struct symbol *lookup_symbol_linkage (const char *linkage_name);
-/* Lookup a type within a class or a namespace. */
-
-extern struct type *lookup_nested_type (struct type *parent_type,
- const char *nested_name,
- const struct block *block);
-
/* A default version of lookup_symbol_nonlocal for use by languages
that can't think of anything better to do. */