aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/cp-namespace.c50
-rw-r--r--gdb/std-operator.def11
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.cp/local-static.exp12
-rw-r--r--gdb/testsuite/gdb.cp/m-static.exp5
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"