diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/cp-namespace.c | 50 | ||||
-rw-r--r-- | gdb/std-operator.def | 11 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/local-static.exp | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/m-static.exp | 5 |
6 files changed, 61 insertions, 29 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a7b4e57..cdcbfae 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2017-09-04 Pedro Alves <palves@redhat.com> + * cp-namespace.c (cp_search_static_and_baseclasses): Handle + function/method scopes; lookup the nested name as a function local + static variable. + +2017-09-04 Pedro Alves <palves@redhat.com> + (%type <voidval>): Add function_method. * c-exp.y (exp): New production for calls with no arguments. (function_method, function_method_void_or_typelist): New diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index b96c421..c7b5aa8 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -246,40 +246,44 @@ cp_search_static_and_baseclasses (const char *name, unsigned int prefix_len, int is_in_anonymous) { - struct block_symbol sym; - struct block_symbol klass_sym; - struct type *klass_type; - /* Check for malformed input. */ if (prefix_len + 2 > strlen (name) || name[prefix_len + 1] != ':') return null_block_symbol; - /* Find the name of the class and the name of the method, variable, etc. */ - - /* The class name is everything up to and including PREFIX_LEN. */ - std::string klass (name, prefix_len); + /* The class, namespace or function name is everything up to and + including PREFIX_LEN. */ + std::string scope (name, prefix_len); /* The rest of the name is everything else past the initial scope operator. */ - std::string nested (name + prefix_len + 2); - - /* Lookup a class named KLASS. If none is found, there is nothing - more that can be done. KLASS could be a namespace, so always look - in VAR_DOMAIN. This works for classes too because of - symbol_matches_domain (which should be replaced with something else, - but it's what we have today). */ - klass_sym = lookup_global_symbol (klass.c_str (), block, VAR_DOMAIN); - if (klass_sym.symbol == NULL) + const char *nested = name + prefix_len + 2; + + /* Lookup the scope symbol. If none is found, there is nothing more + that can be done. SCOPE could be a namespace, so always look in + VAR_DOMAIN. This works for classes too because of + symbol_matches_domain (which should be replaced with something + else, but it's what we have today). */ + block_symbol scope_sym = lookup_symbol_in_static_block (scope.c_str (), + block, VAR_DOMAIN); + if (scope_sym.symbol == NULL) + scope_sym = lookup_global_symbol (scope.c_str (), block, VAR_DOMAIN); + if (scope_sym.symbol == NULL) return null_block_symbol; - klass_type = SYMBOL_TYPE (klass_sym.symbol); - /* Look for a symbol named NESTED in this class. + struct type *scope_type = SYMBOL_TYPE (scope_sym.symbol); + + /* If the scope is a function/method, then look up NESTED as a local + static variable. E.g., "print 'function()::static_var'". */ + if (TYPE_CODE (scope_type) == TYPE_CODE_FUNC + || TYPE_CODE (scope_type) == TYPE_CODE_METHOD) + return lookup_symbol (nested, SYMBOL_BLOCK_VALUE (scope_sym.symbol), + VAR_DOMAIN, NULL); + + /* Look for a symbol named NESTED in this class/namespace. The caller is assumed to have already have done a basic lookup of NAME. So we pass zero for BASIC_LOOKUP to cp_lookup_nested_symbol_1 here. */ - sym = cp_lookup_nested_symbol_1 (klass_type, nested.c_str (), name, - block, domain, 0, is_in_anonymous); - - return sym; + return cp_lookup_nested_symbol_1 (scope_type, nested, name, + block, domain, 0, is_in_anonymous); } /* Look up NAME in the C++ namespace NAMESPACE. Other arguments are diff --git a/gdb/std-operator.def b/gdb/std-operator.def index 56a9af9..344ba25 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -298,7 +298,16 @@ OP (OP_SCOPE) p 'S:method() const'::var then the C-specific handling directly in the parser takes over (see - "block/variable productions). */ + "block/variable productions). + + Also, if the whole function+var is quoted like this: + + p 'S:method() const::var' + + then the whole quoted expression is interpreted as a single symbol + name and we don't use OP_FUNC_STATIC_VAR either. In that case, the + C++-specific symbol lookup routines take care of the + function-local-static search. */ OP (OP_FUNC_STATIC_VAR) /* OP_TYPE is for parsing types, and used with the "ptype" command diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 58ff7f3..ddea68b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2017-09-04 Pedro Alves <palves@redhat.com> + * gdb.base/local-static.exp: Also test with + class::method::variable wholly quoted. + * gdb.cp/m-static.exp (class::method::variable): Remove test. + +2017-09-04 Pedro Alves <palves@redhat.com> + * gdb.base/local-static.c: New. * gdb.base/local-static.cc: New. * gdb.base/local-static.exp: New. diff --git a/gdb/testsuite/gdb.cp/local-static.exp b/gdb/testsuite/gdb.cp/local-static.exp index ba0c5ef..581efa3 100644 --- a/gdb/testsuite/gdb.cp/local-static.exp +++ b/gdb/testsuite/gdb.cp/local-static.exp @@ -95,6 +95,11 @@ proc do_test {lang} { # # 'func()'::var # func()::var + # 'func()::var' + # + # In C++, the latter case makes sure that symbol lookup finds the + # debug symbol instead of the minimal symbol with that exact same + # name. foreach scope_line $scopes_list { set scope [lindex $scope_line 0] @@ -105,6 +110,13 @@ proc do_test {lang} { gdb_test "print '${scope}'::${var_prefix}_${var}" $print_re gdb_test "print ${scope}::${var_prefix}_${var}" $print_re + + set sym "${scope}::${var_prefix}_${var}" + if {$lang == "c++"} { + gdb_test "print '${sym}'" $print_re + } else { + gdb_test "print '${sym}'" "No symbol \"$sym\" in current context\\." + } } } diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp index eeb88e9..10239a3 100644 --- a/gdb/testsuite/gdb.cp/m-static.exp +++ b/gdb/testsuite/gdb.cp/m-static.exp @@ -52,11 +52,6 @@ gdb_continue_to_breakpoint "end of constructors" # One. -# simple object, static const int, accessing via 'class::method::variable' -# Regression test for PR c++/15203 and PR c++/15210 -gdb_test "print (int) 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \ - "simple object, static int, accessing via 'class::method::variable'" - # simple object, static const bool gdb_test "print test1.test" "\\$\[0-9\]* = true" "simple object, static const bool" |