diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index caf4833e49..13e4958841 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-08-18 Keith Seitz + + PR c++/12266 + * gdb.cp/meth-typedefs.cc: New file. + * gdb.cp/meth-typedefs.exp: New file. + 2011-08-17 Phil Muldoon * gdb.python/python.exp: Add extended-prompt tests. diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.cc b/gdb/testsuite/gdb.cp/meth-typedefs.cc new file mode 100644 index 0000000000..d1b7c7fb20 --- /dev/null +++ b/gdb/testsuite/gdb.cp/meth-typedefs.cc @@ -0,0 +1,151 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contributed by Red Hat, originally written by Keith Seitz. */ + +#include + +typedef const char* const* my_type; +typedef int my_type_2; +typedef my_type my_other_type; +typedef my_type_2 my_other_type_2; +typedef unsigned long CORE_ADDR; +typedef enum {E_A, E_B, E_C} anon_enum; +typedef struct {int a; char b;} anon_struct; +typedef union {int a; char b;} anon_union; +typedef anon_enum aenum; +typedef anon_struct astruct; +typedef anon_union aunion; + +typedef void (*fptr1) (my_other_type); +typedef void (*fptr2) (fptr1, my_other_type_2); +typedef void (*fptr3) (fptr2, my_other_type); +typedef void (*fptr4) (anon_enum a, anon_struct const& b, anon_union const*** c); + +namespace A +{ + class foo + { + public: + foo (void) { } + foo (my_other_type a) { } // A::FOO::foo(my_other_type) + foo (my_other_type_2 a) { } // A::FOO::foo(my_other_type_2) + foo (my_other_type_2 a, const my_other_type b) { } // A::FOO::foo(my_other_type_2, const my_other_type) + foo (fptr3) { } // A::FOO::foo(fptr3) + foo (fptr1* a) { } // A::FOO::foo(fptr1*) + foo (CORE_ADDR (*) [10]) { } // A::FOO::foo(CORE_ADDR (*) [10]) + foo (aenum a, astruct const& b, aunion const*** c) { } // A::FOO::foo(aenum, astruct const&, aunion const***) + + void test (my_other_type a) { } // A::FOO::test(my_other_type) + void test (my_other_type_2 a) { } // A::FOO::test(my_other_type_2) + void test (my_other_type_2 a, const my_other_type b) { } // A::FOO::test(my_other_type_2, const my_other_type) + void test (fptr3 a) { } // A::FOO::test(fptr3) + void test (fptr1* a) { } // A::FOO::test(fptr1*) + void test (CORE_ADDR (*) [10]) { } // A::FOO::test(CORE_ADDR (*) [10]) + void test (aenum a, astruct const& b, aunion const*** c) { }; // A::FOO::test(aenum, astruct const&, aunion const***) + }; + + typedef foo FOO; +}; + +namespace B +{ + void + test (my_other_type foo) { } // B::test(my_other_type) + + void + test (aenum a, astruct const& b, aunion const*** c) { } // B::test(aenum, astruct const&, aunion const***) + + template + void test (T1 a, T2 b) { } // B::test (T1, T2) + + template <> + void test (my_other_type foo, my_other_type_2) { } // B::test(my_other_type, my_other_type_2) +}; + +namespace a +{ + namespace b + { + namespace c + { + namespace d + { + class bar { }; + } + } + + typedef c::d::bar BAR; + } +} + +typedef a::b::BAR _BAR_; + +template +void test (T1 a, T2 b) {} // test (T1, T2) + +template <> +void test (my_other_type foo, my_other_type_2) { } // test(my_other_type, my_other_type_2) + +void +test (my_other_type foo) { } // test(my_other_type) + +void +test (_BAR_ &b) { } // test(_BAR_&) + +void +test (aenum a, astruct const& b, aunion const*** c) { } // test(aenum, astruct const&, aunion const***) + +int +main (void) +{ + A::FOO my_foo; + fptr1 fptr; + astruct as = { 0, 0 }; + aunion const au = { 0 }; + aunion const* aup = &au; + aunion const** aupp = &aup; + aunion const*** auppp = &aupp; + + my_foo.test (static_cast (NULL)); + my_foo.test (0); + my_foo.test (0, static_cast (NULL)); + my_foo.test (static_cast (NULL)); + my_foo.test (&fptr); + my_foo.test (static_cast (0)); + my_foo.test (E_A, as, auppp); + + B::test (static_cast (NULL)); + B::test (static_cast (NULL), 0); + B::test (E_A, as, auppp); + + test (static_cast (NULL)); + test (static_cast (NULL), 0); + test (E_A, as, auppp); + + A::foo a (static_cast (NULL)); + A::foo b (0); + A::foo c (0, static_cast (NULL)); + A::foo d (static_cast (NULL)); + A::foo e (&fptr); + A::foo f (static_cast (0)); + A::foo g (E_A, as, auppp); + + fptr4 f4; + + return 0; +} diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp new file mode 100644 index 0000000000..f80a735dd7 --- /dev/null +++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp @@ -0,0 +1,160 @@ +# Copyright 2011 Free Software Foundation, Inc. +# +# Contributed by Red Hat, originally written by Keith Seitz. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This file is part of the gdb testsuite. + +proc add {var name params expected {kind {func}}} { + upvar $var result + + if {[string compare $kind "template"] == 0} { + set method_name "${name}<$expected>" + } else { + set method_name "$name" + } + + set expect ".*// ${method_name}\\($expected\\)" + lappend result [list "${method_name}($params)" $expect] +} + +if {[skip_cplus_tests]} { continue } + +# Tests for c++/12266 et al +set testfile "meth-typedefs" +set srcfile $testfile.cc + +if {[prepare_for_testing $testfile $testfile $srcfile {c++ debug}]} { + return -1 +} + +if {![runto_main]} { + perror "couldn't run to breakpoint" + continue +} + +array set typedefs { + "my_other_type" {"my_other_type" "my_type" "const char* const*"} + "my_other_type_2" {"my_other_type_2" "my_type_2" "int"} + "CORE_ADDR" { "CORE_ADDR" "unsigned long" } + "_BAR_" { "_BAR_" "a::b::BAR" "a::b::c::d::bar" } + "aenum" { "aenum" "anon_enum" } + "astruct" { "astruct" "anon_struct" } + "aunion" { "aunion" "anon_union" } +} + +set methods {} + +# Add the simple, one-parameter methods +foreach meth {A::FOO::test A::FOO::foo} { + foreach type {my_other_type my_other_type_2} { + foreach t $typedefs($type) { + add methods $meth $t $type + } + } +} + +# Add two-parameter methods +foreach meth {A::FOO::test A::FOO::foo} { + set type "my_other_type_2, const my_other_type" + foreach t1 $typedefs(my_other_type_2) { + foreach t2 $typedefs(my_other_type) { + add methods $meth "$t1, const $t2" $type + add methods $meth "$t1, $t2" $type + } + } +} + +# Add three-parameter methods/functions +foreach meth {A::FOO::test A::FOO::foo B::test test} { + set type "aenum, astruct const&, aunion const\\*\\*\\*" + foreach t1 $typedefs(aenum) { + foreach t2 $typedefs(astruct) { + foreach t3 $typedefs(aunion) { + add methods $meth "$t1, $t2 const&, $t3 const***" $type + } + } + } +} + +# Add the array-of-function pointer methods +set type "fptr1\\*" +foreach meth {A::FOO::test A::FOO::foo} { + add methods $meth "fptr1*" $type + foreach t $typedefs(my_other_type) { + add methods $meth "void (**) ($t)" $type + } +} + +# Add the function pointer methods +set type "fptr3" +foreach meth {A::FOO::test A::FOO::foo} { + add methods $meth "fptr3" $type + + foreach t1 $typedefs(my_other_type) { + add methods $meth "void (*)(fptr2, $t1)" $type + foreach t2 $typedefs(my_other_type_2) { + add methods $meth "void (*)(void (*)(fptr1, $t2), $t1)" $type + foreach t3 $typedefs(my_other_type) { + add methods $meth \ + "void (*)(void (*)(void (*) ($t3), $t2), $t1)" $type + } + } + } +} + +set type1 "my_other_type" +set type2 "my_other_type, my_other_type_2" +foreach meth {"test" "B::test"} { + foreach t1 $typedefs(my_other_type) { + add methods $meth $t1 $type1 + foreach t2 $typedefs(my_other_type_2) { + add methods $meth "$t1, $t2" $type2 template + } + } +} + +# Miscellaneous tests +set type {CORE_ADDR \(\*\) \[10\]} +foreach meth {A::FOO::foo A::FOO::test} { + foreach t $typedefs(CORE_ADDR) { + add methods $meth "$t (*) \[10\]" $type + } +} + +foreach t $typedefs(_BAR_) { + add methods "test" "$t&" {_BAR_&} +} + +gdb_test_no_output "set listsize 1" "" + +# Finally, for each method in the list METHODS, check whether +# the user can "list" it and "break" on it (both quoted and unquoted). +foreach test $methods { + set func [lindex $test 0] + set result [lindex $test 1] + + gdb_test "list $func" $result + gdb_test "list '$func'" $result + if {[gdb_breakpoint $func]} { + pass "break $func" + } + if {[gdb_breakpoint '$func']} { + pass "break '$func'" + } +} + +gdb_exit +return 0