From 50af5481d5feece564c8b03bfb4a647dc7573f3c Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 13 Jun 2012 16:10:10 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 12 ++++++++++++ gdb/c-exp.y | 33 ++++++++++++++++++++------------ gdb/cp-namespace.c | 23 +++++++++++----------- gdb/cp-support.h | 6 +++--- gdb/testsuite/ChangeLog | 11 +++++++++++ gdb/testsuite/gdb.cp/cpexprs.cc | 25 ++++++++++++++++++++++++ gdb/testsuite/gdb.cp/cpexprs.exp | 21 ++++++++++++++++++++ 7 files changed, 104 insertions(+), 27 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 304adc62967..ee7e9cb093b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2012-06-13 Jan Kratochvil + + 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 * breakpoint.c (condition_completer): New function. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index e912657754d..1e14337da42 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 170dd5f82f9..e2291a9938f 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 9c150f80159..0d2b5131b54 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 d369a2a2630..d12bd9e8cab 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2012-06-13 Jan Kratochvil + + 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 * 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 c8c5ac8a2a7..f6b355c3d54 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 13af2656ce6..1ae7dc0c2f0 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\]+ )\r\n$gdb_prompt $" { + # = {void (CV * const, CV::t)} 0x400944 + 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]+ } +gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ } +gdb_test "p CV_f(CV::i)" " = 43" + gdb_exit return 0 -- 2.30.2