1# Copyright 2022-2023 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
15
16# Test setting a breakpoint at "f(std::string)".
17#
18# GDB should be able to expand the std::string typedef, and then set
19# the breakpoint using the resulting name.  In the Itanium ABI's
20# mangling scheme, "std::string", "std::istream", "std::iostream",
21# "std::ostream" are special, though, they have corresponding standard
22# abbreviations.  The libiberty demangler only expands these standard
23# abbreviations to their full non-typedef underlying type if the
24# DMGL_VERBOSE option is requested.  By default it expands them to the
25# user-friendly "std::string", etc. typedefs.  GDB didn't use to use
26# that option, and would instead prevent expansion of the
27# "std::string" (etc.) standard-abbreviation typedefs at
28# breakpoint-set type, such that the function name used for function
29# lookup would match the "std::string" present in the function's
30# non-DMGL_VERBOSE demangled name.
31#
32# For example (DMGL_VERBOSE):
33#
34#  $ echo "_Z1fSs" | c++filt
35#  f(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)
36#
37# vs (no DMGL_VERBOSE):
38#
39#  $ echo "_Z1fSs" | c++filt --no-verbose
40#  f(std::string)
41#
42# This design broke setting a breakpoint at "f(std::string)" when the
43# libstdc++ C++11 ABI was introduced, as the "f(std::string)"
44# function's mangled name no longer uses a standard substitution for
45# std::string...
46#
47# I.e., with the libstdc++ C++11 ABI, we now have (and DMGL_VERBOSE
48# makes no difference):
49#
50#  $ echo _Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE | c++filt
51#  f(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
52#
53# So nowadays, GDB always uses DMGL_VERBOSE and no longer prevents
54# std::string (etc.) typedef expansion.  This test exercises both
55# pre-C++11 and C++11 ABIs for this reason.  On non-libstdc++ systems
56# where _GLIBCXX_USE_CXX11_ABI has no effect, we just end up running
57# the test twice with whatever ABI is used.
58
59standard_testfile .cc
60
61if { [skip_cplus_tests] } { continue }
62
63# CXX11_ABI specifies the value to define _GLIBCXX_USE_CXX11_ABI as.
64
65proc test {cxx11_abi} {
66    global srcdir subdir srcfile binfile testfile
67
68    set options \
69	[list c++ debug additional_flags=-D_GLIBCXX_USE_CXX11_ABI=$cxx11_abi]
70    if { [gdb_compile \
71	      "${srcdir}/${subdir}/${srcfile}" "${binfile}-${cxx11_abi}.o" \
72	      object $options] != "" } {
73	untested "failed to compile"
74	return -1
75    }
76
77    clean_restart ${testfile}-${cxx11_abi}.o
78
79    # Since we're debugging an .o file, GDB doesn't figure out we're
80    # debugging C++ code and the current language when auto, is
81    # guessed as C.
82    gdb_test_no_output "set language c++"
83
84    # Get the type std::string is a typedef for.  We'll try to set a
85    # breakpoint using the expanded type too.
86    set realtype ""
87    set type "std::string"
88    gdb_test_multiple "whatis /r $type" "" {
89	-re -wrap "type = (\[^\r\n\]+)" {
90	    set realtype $expect_out(1,string)
91	    gdb_assert {![string eq "$realtype" "$type"]} \
92		$gdb_test_name
93	}
94    }
95
96    # GDB should be able to expand the std::string typedef in the
97    # function prototype using C++ logic even if the current language
98    # is C.
99    foreach_with_prefix lang {"c" "c++"} {
100	gdb_test_no_output "set language $lang"
101
102	gdb_test "break f($type)" "$srcfile, line $::decimal\\."
103
104	if { $realtype != "" } {
105	    gdb_test "break f($realtype)" "$srcfile, line $::decimal\\."
106	}
107    }
108}
109
110foreach_with_prefix _GLIBCXX_USE_CXX11_ABI {0 1} {
111    test $_GLIBCXX_USE_CXX11_ABI
112}
113