Consider this test-case, using two ways to get to val1: ... $ cat test.c namespace ns { enum e { val1 = 0x1, }; } int main (void) { return (int)ns::e::val1 + (int)ns::val1; } $ g++ -g test.c $ ./a.out ; echo $? 2 ... In gdb, we have: ... $ gdb -q -batch a.out -ex "print ns::val1" $1 = ns::val1 ... but not: ... $ gdb -q -batch a.out -ex "print ns::e::val1" `ns::e' is not defined as an aggregate type. ... In contrast, with lldb we have: ... $ lldb -batch a.out -o "p ns::e::val1" (lldb) target create "a.out" Current executable set to '/home/vries/gdb/a.out' (x86_64). (lldb) p ns::e::val1 (ns::e) $0 = val1 ... but not: ... $ lldb -batch a.out -o "p ns::val1" (lldb) target create "a.out" Current executable set to '/home/vries/gdb/a.out' (x86_64). (lldb) p ns::val1 error: <user expression 0>:1:5: no member named 'val1' in namespace 'ns' ns::val1 ~~~~^ ...
> print ns::e::val1 I did not know this is valid C++.
FWIW, this one is probably not a regression, and also may require adding a second symbol in the full reader as well. Though perhaps it would be better to change the parser to look up "ns::e" and then search the enum type itself for "val1", eliminating the need for any new entries or symbols.
(In reply to Tom Tromey from comment #2) > FWIW, this one is probably not a regression, and also may > require adding a second symbol in the full reader as well. > Though perhaps it would be better to change the parser > to look up "ns::e" and then search the enum type itself > for "val1", eliminating the need for any new entries or symbols. Using this patch: ... diff --git a/gdb/c-exp.y b/gdb/c-exp.y index ca411dc0f5b..98b505793d4 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1129,7 +1129,7 @@ qualified_name: TYPENAME COLONCOLON name { struct type *type = $1.type; type = check_typedef (type); - if (!type_aggregate_p (type)) + if (!type_aggregate_p (type) + && type->code () != TYPE_CODE_ENUM) error (_("`%s' is not defined as an aggregate type."), TYPE_SAFE_NAME (type)); diff --git a/gdb/valops.c b/gdb/valops.c index 427fbb1ad61..00ca7b61a28 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -3394,9 +3394,6 @@ enum_constant_from_type (struct type *type, const char *name) int i; int name_len = strlen (name); - gdb_assert (type->code () == TYPE_CODE_ENUM - && type->is_declared_class ()); - for (i = TYPE_N_BASECLASSES (type); i < type->num_fields (); ++i) { const char *fname = type->field (i).name (); ... we get: ... $ gdb -q -batch -readnow a.out -ex "print ns::e::val1" $1 = ns::val1 ...
(In reply to Tom Tromey from comment #1) > > print ns::e::val1 > > I did not know this is valid C++. I tried to find a reference for this, and here ( https://en.cppreference.com/w/cpp/language/enum ) I found: ... struct X { enum direction { left = 'l', right = 'r' }; }; int a = X::direction::left; // allowed only in C++11 and later ...