diff options
author | David Carlton <carlton@bactrian.org> | 2003-09-25 16:39:39 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2003-09-25 16:39:39 +0000 |
commit | 2f8e2918bfc50c9440b3fe15bc873b2607592b04 (patch) | |
tree | fab384e26ba31fced3e7acf485ba2cd662ba2659 /gdb | |
parent | 18e5fdd7cc447c970b0bda9428d0265cf3225b76 (diff) | |
download | gdb-2f8e2918bfc50c9440b3fe15bc873b2607592b04.tar.gz |
2003-09-25 David Carlton <carlton@kealia.com>
* c-exp.y: Include cp-support.h. Add qualified_type.
(yylex): Delete nested type hack; add comments.
* cp-namespace.c (cp_lookup_nested_type): New function.
* cp-support.h: Declare cp_lookup_nested_type.
* eval.c (evaluate_subexp_standard): Call value_aggregate_elt
instead of value_struct_elt_for_reference.
* valops.c: Include cp-support.h.
(value_aggregate_elt): New function.
(value_namespace_elt): Ditto.
(value_struct_elt_for_reference): Make static.
* value.h: Delete declaration of value_struct_elt_for_reference;
add declaration for value_aggregate_elt.
* Makefile.in (c-exp.tab.o): Depend on $(cp_support_h).
(valops.o): Ditto.
2003-09-25 David Carlton <carlton@kealia.com>
* gdb.cp/namespace.exp: Tweak comments. Add non-quoted versions
of some print tests, where appropriate. Add tests for C::D::cd,
E::ce, F::cXfX, G::XgX.
* gdb.cp/namespace.cc: Add XgX, cXfX, ce.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/Makefile.in | 5 | ||||
-rw-r--r-- | gdb/c-exp.y | 179 | ||||
-rw-r--r-- | gdb/cp-namespace.c | 35 | ||||
-rw-r--r-- | gdb/cp-support.h | 4 | ||||
-rw-r--r-- | gdb/eval.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/namespace.cc | 19 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/namespace.exp | 42 | ||||
-rw-r--r-- | gdb/valops.c | 67 | ||||
-rw-r--r-- | gdb/value.h | 8 |
11 files changed, 288 insertions, 103 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 446914ed0e1..f7a0c9e5457 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2003-09-25 David Carlton <carlton@kealia.com> + + * c-exp.y: Include cp-support.h. Add qualified_type. + (yylex): Delete nested type hack; add comments. + * cp-namespace.c (cp_lookup_nested_type): New function. + * cp-support.h: Declare cp_lookup_nested_type. + * eval.c (evaluate_subexp_standard): Call value_aggregate_elt + instead of value_struct_elt_for_reference. + * valops.c: Include cp-support.h. + (value_aggregate_elt): New function. + (value_namespace_elt): Ditto. + (value_struct_elt_for_reference): Make static. + * value.h: Delete declaration of value_struct_elt_for_reference; + add declaration for value_aggregate_elt. + * Makefile.in (c-exp.tab.o): Depend on $(cp_support_h). + (valops.o): Ditto. + 2003-09-25 Daniel Jacobowitz <drow@mvista.com> * stack.c: Include "reggroups.h". diff --git a/gdb/Makefile.in b/gdb/Makefile.in index aea9f3ccf9a..c61f1bfbca5 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) @@ -2418,7 +2418,8 @@ valarith.o: valarith.c $(defs_h) $(value_h) $(symtab_h) $(gdbtypes_h) \ valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \ $(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \ $(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(block_h) $(infcall_h) \ - $(dictionary_h) $(cp_support_h) $(gdb_string_h) $(gdb_assert_h) + $(dictionary_h) $(cp_support_h) $(gdb_string_h) $(gdb_assert_h) \ + $(cp_support_h) valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \ $(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h) diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 34f7729eb5f..0c279db23d1 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; @@ -153,7 +154,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %type <voidval> exp exp1 type_exp start variable qualified_name lcurly %type <lval> rcurly -%type <tval> type typebase +%type <tval> type typebase qualified_type %type <tvec> nonempty_typelist /* %type <bval> block */ @@ -595,7 +596,8 @@ qualified_name: typebase COLONCOLON name { struct type *type = $1; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -609,7 +611,8 @@ qualified_name: typebase COLONCOLON name struct type *type = $1; struct stoken tmp_token; if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) + && TYPE_CODE (type) != TYPE_CODE_UNION + && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) error ("`%s' is not defined as an aggregate type.", TYPE_NAME (type)); @@ -888,6 +891,80 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = follow_types ($2); } | typebase const_or_volatile_or_space_identifier_noopt { $$ = follow_types ($1); } + | qualified_type + ; + +/* 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: 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... */ + +/* FIXME: carlton/2003-09-25: Currently, the only qualified type + symbols that we generate are nested namespaces. Next on my TODO + list is to generate all nested type names properly (or at least as + well as possible, assuming that we're using DWARF-2). */ + +qualified_type: typebase COLONCOLON name + { + struct type *type = $1; + struct type *new_type; + char *ncopy = alloca ($3.length + 1); + + memcpy (ncopy, $3.ptr, $3.length); + ncopy[$3.length] = '\0'; + + if (TYPE_CODE (type) != TYPE_CODE_NAMESPACE) + error ("`%s' is not defined as a namespace.", + TYPE_NAME (type)); + + new_type = cp_lookup_nested_type (type, ncopy, + expression_context_block); + if (new_type == NULL) + error ("No type \"%s\" in namespace \"%s\".", + ncopy, TYPE_NAME (type)); + + $$ = new_type; + } ; typename: TYPENAME @@ -1633,7 +1710,13 @@ yylex () string to get a reasonable class/namespace spec or a fully-qualified name. This is a kludge to get around the HP aCC compiler's generation of symbol names with embedded - colons for namespace and nested classes. */ + colons for namespace and nested classes. */ + + /* 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 */ @@ -1687,92 +1770,10 @@ yylex () if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) { -#if 1 - /* Despite the following flaw, we need to keep this code enabled. - Because we can get called from check_stub_method, if we don't - handle nested types then it screws many operations in any - program which uses nested types. */ - /* In "A::x", if x is a member function of A and there happens - to be a type (nested or not, since the stabs don't make that - distinction) named x, then this code incorrectly thinks we - are dealing with nested types rather than a member function. */ - - char *p; - char *namestart; - struct symbol *best_sym; - - /* 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. */ - - /* Since we do not currently have any way of distinguishing - a nested type from a non-nested one (the stabs don't tell - us whether a type is nested), we just ignore the - containing type. */ - - p = lexptr; - best_sym = 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 symbol *cur_sym; - /* As big as the whole rest of the expression, which is - at least big enough. */ - char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3); - char *tmp1; - - tmp1 = ncopy; - memcpy (tmp1, tmp, strlen (tmp)); - tmp1 += strlen (tmp); - memcpy (tmp1, "::", 2); - tmp1 += 2; - memcpy (tmp1, namestart, p - namestart); - tmp1[p - namestart] = '\0'; - cur_sym = lookup_symbol (ncopy, expression_context_block, - VAR_DOMAIN, (int *) NULL, - (struct symtab **) NULL); - if (cur_sym) - { - if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) - { - best_sym = cur_sym; - lexptr = p; - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - - yylval.tsym.type = SYMBOL_TYPE (best_sym); -#else /* not 0 */ + /* 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 0 */ return TYPENAME; } if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 40959a589a4..75104ac2d6e 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -508,6 +508,41 @@ 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. Return NULL if there is no such nested type. */ + +/* FIXME: carlton/2003-09-24: For now, this only works for nested + namespaces; the patch to make this work on other sorts of nested + types is next on my TODO list. */ + +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_NAMESPACE: + { + 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: + internal_error (__FILE__, __LINE__, + "cp_lookup_nested_type called on a non-namespace."); + } +} + /* Now come functions for dealing with symbols associated to namespaces. (They're used to store the namespaces themselves, not objects that live in the namespaces.) These symbols come in two diff --git a/gdb/cp-support.h b/gdb/cp-support.h index 169fbaf71c3..d8cb5252d55 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -97,6 +97,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/eval.c b/gdb/eval.c index cda14946eb6..a44d0c7fbe2 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -408,11 +408,9 @@ evaluate_subexp_standard (struct type *expect_type, case OP_SCOPE: tem = longest_to_int (exp->elts[pc + 2].longconst); (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type, - 0, - exp->elts[pc + 1].type, - &exp->elts[pc + 3].string, - NULL_TYPE); + arg1 = value_aggregate_elt (exp->elts[pc + 1].type, + &exp->elts[pc + 3].string, + noside); if (arg1 == NULL) error ("There is no field named %s", &exp->elts[pc + 3].string); return arg1; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f3981c13007..5c18f82152c 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2003-09-25 David Carlton <carlton@kealia.com> + + * gdb.cp/namespace.exp: Tweak comments. Add non-quoted versions + of some print tests, where appropriate. Add tests for C::D::cd, + E::ce, F::cXfX, G::XgX. + * gdb.cp/namespace.cc: Add XgX, cXfX, ce. + 2003-09-25 Richard Earnshaw <rearnsha@arm.com> * lib/java.exp (java_init): Import target_alias before using it. diff --git a/gdb/testsuite/gdb.cp/namespace.cc b/gdb/testsuite/gdb.cp/namespace.cc index 7b9a173d819..a0814ee707c 100644 --- a/gdb/testsuite/gdb.cp/namespace.cc +++ b/gdb/testsuite/gdb.cp/namespace.cc @@ -75,6 +75,11 @@ namespace namespace G { int Xg = 10; + + namespace + { + int XgX = 11; + } } } @@ -90,6 +95,11 @@ namespace C namespace F { int cXf = 7; + + namespace + { + int cXfX = 8; + } } } @@ -98,6 +108,11 @@ namespace C int cc = 2; } + namespace E + { + int ce = 4; + } + namespace D { int cd = 3; @@ -118,14 +133,18 @@ namespace C //cc; C::cc; cd; + //C::D::cd; E::cde; shadow; + //E::ce; cX; F::cXf; + F::cXfX; X; G::Xg; //cXOtherFile; //XOtherFile; + G::XgX; return; } diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp index 6952c8fb53c..228d791ad66 100644 --- a/gdb/testsuite/gdb.cp/namespace.exp +++ b/gdb/testsuite/gdb.cp/namespace.exp @@ -18,11 +18,11 @@ # bug-gdb@prep.ai.mit.edu # tests for namespaces -# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23 +# Originally written by Satish Pai <pai@apollo.hp.com> 1997-07-23 # This file is part of the gdb testsuite -# Note: These tests are geared to the HP aCC compiler, +# Note: The original tests were geared to the HP aCC compiler, # which has an idiosyncratic way of emitting debug info # for namespaces. # Note: As of 2000-06-03, these pass under g++ - djb @@ -84,6 +84,11 @@ gdb_test "up" ".*main.*" "up from marker1" # Access a data item inside a namespace using colons and # single quotes :-( +# NOTE: carlton/2003-09-24: the quotes are becoming less necessary (or +# even desirable.) For tests where it should still work with quotes, +# I'm including versions both with and without quotes; for tests that +# shouldn't work with quotes, I'm only including one version. + send_gdb "print 'AAA::c'\n" gdb_expect { -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print 'AAA::c'" } @@ -91,6 +96,13 @@ gdb_expect { timeout { fail "(timeout) print 'AAA::c'" } } +send_gdb "print AAA::c\n" +gdb_expect { + -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print AAA::c" } + -re ".*$gdb_prompt $" { fail "print AAA::c" } + timeout { fail "(timeout) print AAA::c" } +} + # An object declared using "using". send_gdb "print ina\n" @@ -137,6 +149,15 @@ gdb_expect { timeout { fail "(timeout) print 'AAA::xyzq'('x')" } } +send_gdb "print AAA::xyzq('x')\n" +gdb_expect { + -re "\\$\[0-9\]* = 97 'a'\r\n$gdb_prompt $" { + pass "print AAA::xyzq('x')" + } + -re ".*$gdb_prompt $" { fail "print AAA::xyzq('x')" } + timeout { fail "(timeout) print AAA::xyzq('x')" } +} + # Break on a function in a namespace send_gdb "break AAA::xyzq\n" @@ -159,6 +180,15 @@ gdb_expect { timeout { fail "(timeout) print 'BBB::CCC::xyzq'('x')" } } +send_gdb "print BBB::CCC::xyzq('x')\n" +gdb_expect { + -re "\\$\[0-9\]* = 122 'z'\r\n$gdb_prompt $" { + pass "print BBB::CCC::xyzq('x')" + } + -re ".*$gdb_prompt $" { fail "print BBB::CCC::xyzq('x')" } + timeout { fail "(timeout) print BBB::CCC::xyzq('x')" } +} + # Break on a function in a nested namespace send_gdb "break BBB::CCC::xyzq\n" @@ -204,9 +234,13 @@ if ![runto "C::D::marker2"] then { gdb_test "print c" "\\$\[0-9\].* = 1" gdb_test "print cc" "No symbol \"cc\" in current context." gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2" +gdb_test "print C::cc" "\\$\[0-9\].* = 2" gdb_test "print cd" "\\$\[0-9\].* = 3" +gdb_test "print C::D::cd" "No type \"D\" in namespace \"C::C\"." gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5" +gdb_test "print E::cde" "\\$\[0-9\].* = 5" gdb_test "print shadow" "\\$\[0-9\].* = 13" +gdb_test "print E::ce" "No symbol \"ce\" in namespace \"C::D::E\"." gdb_test "print cOtherFile" "\\$\[0-9\].* = 316" gdb_test "ptype C" "type = namespace C::C" gdb_test "ptype E" "type = namespace C::D::E" @@ -215,7 +249,11 @@ gdb_test "ptype E" "type = namespace C::D::E" gdb_test "print cX" "\\$\[0-9\].* = 6" gdb_test "print 'F::cXf'" "\\$\[0-9\].* = 7" +gdb_test "print F::cXf" "\\$\[0-9\].* = 7" +gdb_test "print F::cXfX" "\\$\[0-9\].* = 8" gdb_test "print X" "\\$\[0-9\].* = 9" gdb_test "print 'G::Xg'" "\\$\[0-9\].* = 10" +gdb_test "print G::Xg" "\\$\[0-9\].* = 10" +gdb_test "print G::XgX" "\\$\[0-9\].* = 11" gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context." gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context." diff --git a/gdb/valops.c b/gdb/valops.c index 8deb473a083..08036de5e2c 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -41,6 +41,7 @@ #include <errno.h> #include "gdb_string.h" #include "gdb_assert.h" +#include "cp-support.h" /* Flag indicating HP compilers were used; needed to correctly handle some value operations with HP aCC code/runtime. */ @@ -63,6 +64,17 @@ static struct value *search_struct_method (char *, struct value **, static int check_field_in (struct type *, const char *); + +static struct value *value_struct_elt_for_reference (struct type *domain, + int offset, + struct type *curtype, + char *name, + struct type *intype); + +static struct value *value_namespace_elt (const struct type *curtype, + const char *name, + enum noside noside); + static CORE_ADDR allocate_space_in_inferior (int); static struct value *cast_into_complex (struct type *, struct value *); @@ -2208,6 +2220,30 @@ check_field (struct value *arg1, const char *name) } /* C++: Given an aggregate type CURTYPE, and a member name NAME, + return the appropriate member. This function is used to resolve + user expressions of the form "DOMAIN::NAME". For more details on + what happens, see the comment before + value_struct_elt_for_reference. */ + +struct value * +value_aggregate_elt (struct type *curtype, + char *name, + enum noside noside) +{ + switch (TYPE_CODE (curtype)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL); + case TYPE_CODE_NAMESPACE: + return value_namespace_elt (curtype, name, noside); + default: + internal_error (__FILE__, __LINE__, + "non-aggregate type in value_aggregate_elt"); + } +} + +/* C++: Given an aggregate type CURTYPE, and a member name NAME, return the address of this member as a "pointer to member" type. If INTYPE is non-null, then it will be the type of the member we are looking for. This will help us resolve @@ -2347,6 +2383,37 @@ value_struct_elt_for_reference (struct type *domain, int offset, return 0; } +/* C++: Return the member NAME of the namespace given by the type + CURTYPE. */ + +static struct value * +value_namespace_elt (const struct type *curtype, + const char *name, + enum noside noside) +{ + const char *namespace_name = TYPE_TAG_NAME (curtype); + struct symbol *sym; + struct value *retval; + + sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, + get_selected_block (0), VAR_DOMAIN, + NULL); + + if (sym == NULL) + retval = NULL; + else if ((noside == EVAL_AVOID_SIDE_EFFECTS) + && (SYMBOL_CLASS (sym) == LOC_TYPEDEF)) + retval = allocate_value (SYMBOL_TYPE (sym)); + else + retval = value_of_variable (sym, get_selected_block (0)); + + if (retval == NULL) + error ("No symbol \"%s\" in namespace \"%s\".", name, + TYPE_TAG_NAME (curtype)); + + return retval; +} + /* Given a pointer value V, find the real (RTTI) type of the object it points to. diff --git a/gdb/value.h b/gdb/value.h index afec1609e7b..2040c86381d 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -379,11 +379,9 @@ extern struct value *value_struct_elt (struct value **argp, char *name, int *static_memfuncp, char *err); -extern struct value *value_struct_elt_for_reference (struct type *domain, - int offset, - struct type *curtype, - char *name, - struct type *intype); +extern struct value *value_aggregate_elt (struct type *curtype, + char *name, + enum noside noside); extern struct value *value_static_field (struct type *type, int fieldno); |