aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2012-06-13 16:10:10 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2012-06-13 16:10:10 +0000
commit50af5481d5feece564c8b03bfb4a647dc7573f3c (patch)
tree6d434da197be7f970b21ecc8f8f4afc417571b76
parentd55637df6923689396e58c3d789e82314f4826ec (diff)
downloadgdb-50af5481d5feece564c8b03bfb4a647dc7573f3c.zip
gdb-50af5481d5feece564c8b03bfb4a647dc7573f3c.tar.gz
gdb-50af5481d5feece564c8b03bfb4a647dc7573f3c.tar.bz2
gdb/
PR c++/14177 - Fix parsing TYPENAME:: in parentheses. * c-exp.y (classify_inner_name): Remove caller assumptions in the function comment. Return ERROR for unresolved cases. Implement returning proper NAME. (yylex): Accept also NAME from classify_inner_name. * cp-namespace.c (cp_lookup_nested_type): Rename to ... (cp_lookup_nested_symbol): ... here. Return any found symbol, not just LOC_TYPEDEF type. * cp-support.h (cp_lookup_nested_type): Update its declaration. gdb/testsuite/ PR c++/14177 - Fix parsing TYPENAME:: in parentheses. * gdb.cp/cpexprs.cc (class CV, CV::i, ATTRIBUTE_USED, CV_f): New. (test_function): Call CV_f. * gdb.cp/cpexprs.exp (p 'CV::m(int)', p CV::m(int)) (p 'CV::m(int) const', p CV::m(int) const, p 'CV::m(int) volatile') (p CV::m(int) volatile, p 'CV::m(int) const volatile') (p CV::m(int) const volatile, p CV_f(int), p CV_f(CV::t)) (p CV_f(CV::i)): New tests.
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/c-exp.y33
-rw-r--r--gdb/cp-namespace.c23
-rw-r--r--gdb/cp-support.h6
-rw-r--r--gdb/testsuite/ChangeLog11
-rw-r--r--gdb/testsuite/gdb.cp/cpexprs.cc25
-rw-r--r--gdb/testsuite/gdb.cp/cpexprs.exp21
7 files changed, 104 insertions, 27 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 304adc6..ee7e9cb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,15 @@
+2012-06-13 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR c++/14177 - Fix parsing TYPENAME:: in parentheses.
+ * c-exp.y (classify_inner_name): Remove caller assumptions in the
+ function comment. Return ERROR for unresolved cases. Implement
+ returning proper NAME.
+ (yylex): Accept also NAME from classify_inner_name.
+ * cp-namespace.c (cp_lookup_nested_type): Rename to ...
+ (cp_lookup_nested_symbol): ... here. Return any found symbol, not just
+ LOC_TYPEDEF type.
+ * cp-support.h (cp_lookup_nested_type): Update its declaration.
+
2012-06-13 Tom Tromey <tromey@redhat.com>
* breakpoint.c (condition_completer): New function.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index e912657..1e14337 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -2505,9 +2505,8 @@ classify_name (struct block *block)
/* Like classify_name, but used by the inner loop of the lexer, when a
name might have already been seen. FIRST_NAME is true if the token
- in `yylval' is the first component of a name, false otherwise. If
- this function returns NAME, it might not have updated `yylval'.
- This is ok because the caller only cares about TYPENAME. */
+ in `yylval' is the first component of a name, false otherwise. */
+
static int
classify_inner_name (struct block *block, int first_name)
{
@@ -2521,18 +2520,28 @@ classify_inner_name (struct block *block, int first_name)
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION
&& TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
- /* We know the caller won't expect us to update yylval. */
- return NAME;
+ return ERROR;
copy = copy_name (yylval.tsym.stoken);
- new_type = cp_lookup_nested_type (yylval.tsym.type, copy, block);
+ yylval.ssym.sym = cp_lookup_nested_symbol (yylval.tsym.type, copy, block);
+ if (yylval.ssym.sym == NULL)
+ return ERROR;
+
+ switch (SYMBOL_CLASS (yylval.ssym.sym))
+ {
+ case LOC_BLOCK:
+ case LOC_LABEL:
+ return ERROR;
- if (new_type == NULL)
- /* We know the caller won't expect us to update yylval. */
- return NAME;
+ case LOC_TYPEDEF:
+ yylval.tsym.type = SYMBOL_TYPE (yylval.ssym.sym);;
+ return TYPENAME;
- yylval.tsym.type = new_type;
- return TYPENAME;
+ default:
+ yylval.ssym.is_a_field_of_this = 0;
+ return NAME;
+ }
+ internal_error (__FILE__, __LINE__, _("not reached"));
}
/* The outer level of a two-level lexer. This calls the inner lexer
@@ -2592,7 +2601,7 @@ yylex (void)
first_iter);
/* We keep going until we either run out of names, or until
we have a qualified name which is not a type. */
- if (classification != TYPENAME)
+ if (classification != TYPENAME && classification != NAME)
{
/* Push the final component and leave the loop. */
VEC_safe_push (token_and_value, token_fifo, &next);
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 170dd5f..e2291a9 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -660,14 +660,14 @@ lookup_symbol_file (const char *name,
return sym;
}
-/* Look up a type named NESTED_NAME that is nested inside the C++
+/* Look up a symbol 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. */
-struct type *
-cp_lookup_nested_type (struct type *parent_type,
- const char *nested_name,
- const struct block *block)
+struct symbol *
+cp_lookup_nested_symbol (struct type *parent_type,
+ const char *nested_name,
+ const struct block *block)
{
/* type_name_no_tag_required provides better error reporting using the
original type. */
@@ -694,8 +694,8 @@ cp_lookup_nested_type (struct type *parent_type,
block, VAR_DOMAIN);
char *concatenated_name;
- if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- return SYMBOL_TYPE (sym);
+ if (sym != NULL)
+ return sym;
/* Now search all static file-level symbols. Not strictly
correct, but more useful than an error. We do not try to
@@ -707,16 +707,15 @@ cp_lookup_nested_type (struct type *parent_type,
+ strlen (nested_name) + 1);
sprintf (concatenated_name, "%s::%s",
parent_name, nested_name);
- sym = lookup_static_symbol_aux (concatenated_name,
- VAR_DOMAIN);
- if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- return SYMBOL_TYPE (sym);
+ sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+ if (sym != NULL)
+ return sym;
return NULL;
}
default:
internal_error (__FILE__, __LINE__,
- _("cp_lookup_nested_type called "
+ _("cp_lookup_nested_symbol called "
"on a non-aggregate type."));
}
}
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 9c150f8..0d2b513 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -213,9 +213,9 @@ extern struct symbol *cp_lookup_symbol_imports_or_template
const struct block *block,
const domain_enum domain);
-extern struct type *cp_lookup_nested_type (struct type *parent_type,
- const char *nested_name,
- const struct block *block);
+extern struct symbol *cp_lookup_nested_symbol (struct type *parent_type,
+ const char *nested_name,
+ const struct block *block);
struct type *cp_lookup_transparent_type (const char *name);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d369a2a..d12bd9e 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2012-06-13 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR c++/14177 - Fix parsing TYPENAME:: in parentheses.
+ * gdb.cp/cpexprs.cc (class CV, CV::i, ATTRIBUTE_USED, CV_f): New.
+ (test_function): Call CV_f.
+ * gdb.cp/cpexprs.exp (p 'CV::m(int)', p CV::m(int))
+ (p 'CV::m(int) const', p CV::m(int) const, p 'CV::m(int) volatile')
+ (p CV::m(int) volatile, p 'CV::m(int) const volatile')
+ (p CV::m(int) const volatile, p CV_f(int), p CV_f(CV::t))
+ (p CV_f(CV::i)): New tests.
+
2012-06-13 Tom Tromey <tromey@redhat.com>
* gdb.base/condbreak.exp: Add tests for "condition" completion.
diff --git a/gdb/testsuite/gdb.cp/cpexprs.cc b/gdb/testsuite/gdb.cp/cpexprs.cc
index c8c5ac8..f6b355c 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.cc
+++ b/gdb/testsuite/gdb.cp/cpexprs.cc
@@ -308,6 +308,29 @@ class derived : public base1, public base2
int foo_;
};
+class CV { public:
+ static const int i;
+ typedef int t;
+ void m(t);
+ void m(t) const;
+ void m(t) volatile;
+ void m(t) const volatile;
+};
+const int CV::i = 42;
+#ifdef __GNUC__
+# define ATTRIBUTE_USED __attribute__((used))
+#else
+# define ATTRIBUTE_USED
+#endif
+ATTRIBUTE_USED void CV::m(CV::t) {}
+ATTRIBUTE_USED void CV::m(CV::t) const {}
+ATTRIBUTE_USED void CV::m(CV::t) volatile {}
+ATTRIBUTE_USED void CV::m(CV::t) const volatile {}
+int CV_f (int x)
+{
+ return x + 1;
+}
+
int
test_function (int argc, char* argv[]) // test_function
{ // test_function
@@ -428,6 +451,8 @@ test_function (int argc, char* argv[]) // test_function
fluff* flp = a;
fluff** flpp = a;
+ CV_f(CV::i);
+
return 0;
}
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp b/gdb/testsuite/gdb.cp/cpexprs.exp
index 13af265..1ae7dc0 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp
@@ -719,5 +719,26 @@ foreach name [get_functions list] {
}
}
+# Test c/v gets recognized even without quoting.
+foreach cv {{} { const} { volatile} { const volatile}} {
+ set test "p 'CV::m(int)$cv'"
+ gdb_test_multiple $test $test {
+ -re "( = {.*} 0x\[0-9a-f\]+ <CV::m.*>)\r\n$gdb_prompt $" {
+ # = {void (CV * const, CV::t)} 0x400944 <CV::m(int)>
+ set correct $expect_out(1,string)
+ pass $test
+ }
+ }
+ if {"$cv" != ""} {
+ setup_kfail c++/14186 *-*-*
+ }
+ gdb_test "p CV::m(int)$cv" [string_to_regexp $correct]
+}
+
+# Test TYPENAME:: gets recognized even in parentheses.
+gdb_test "p CV_f(int)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
+gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
+gdb_test "p CV_f(CV::i)" " = 43"
+
gdb_exit
return 0