# Copyright 2007-2012 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 <http://www.gnu.org/licenses/>.

# This test verifies that setting breakpoint on line in template
# function will fire in all instantiations of that template.

if { [skip_stl_tests] } { continue }

# On SPU this test fails because the executable exceeds local storage size.
if { [istarget "spu*-*-*"] } {
        return 0
}


standard_testfile .cc

if [get_compiler_info "c++"] {
    return -1
}

if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
    return -1
}

set bp_location [gdb_get_line_number "set breakpoint here"]

# Set a breakpoint with multiple locations
# and a condition.

gdb_test "break $srcfile:$bp_location if i==1" \
    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
    "initial condition: set breakpoint"

gdb_run_cmd

set test "initial condition: run to breakpoint"
gdb_test_multiple "" $test {
    -re "Breakpoint \[0-9\]+,.*foo<int> \\(i=1\\).*$gdb_prompt $" {
	pass $test
	break
    }
}

gdb_test "continue" \
    ".*Breakpoint.*foo<double> \\(i=1\\).*" \
    "initial condition: run to breakpoint 2"

# Set breakpoint with multiple locations.
# Separately set the condition.

delete_breakpoints
gdb_test "kill" "" "kill" \
         {Kill the program being debugged\? \(y or n\) } "y"

gdb_test "break $srcfile:$bp_location" \
    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
    "separate condition: set breakpoint"

gdb_test_no_output {condition $bpnum i==1} \
    "separate condition: set condition"
    
gdb_run_cmd
gdb_expect {
    -re "Breakpoint \[0-9\]+,.*foo<int> \\(i=1\\).*$gdb_prompt $" {
	pass "separate condition: run to breakpoint"
    }
    -re "$gdb_prompt $" {
	fail "separate condition: run to breakpoint"
    }
    timeout {
	fail "separate condition: run to breakpoint (timeout)"
    }
}

gdb_test "continue" \
    ".*Breakpoint.*foo<double> \\(i=1\\).*" \
    "separate condition: run to breakpoint 2"

# Try disabling a single location. We also test
# that at least in simple cases, the enable/disable
# state of locations surive "run".
gdb_test_no_output {disable $bpnum.1} "disabling location: disable"

gdb_run_cmd
gdb_expect {
    -re "Breakpoint \[0-9\]+,.*foo<double> \\(i=1\\).*$gdb_prompt $" {
	pass "disabling location: run to breakpoint"
    }
    -re "$gdb_prompt $" {
	fail "disabling location: run to breakpoint"
    }
    timeout {
	fail "disabling location: run to breakpoint (timeout)"
    }
}

# Try disabling entire breakpoint
gdb_test_no_output {enable $bpnum.1} "disabling location: enable"


gdb_test_no_output {disable $bpnum} "disable breakpoint: disable"

gdb_run_cmd
gdb_expect {
    -re "$inferior_exited_re normally.*$gdb_prompt $" {
	pass "disable breakpoint: run to breakpoint"
    }
    -re "$gdb_prompt $" {
	fail "disable breakpoint: run to breakpoint"
    }
    timeout {
	fail "disable breakpoint: run to breakpoint (timeout)"
    }
}

# Make sure breakpoint can be set on a specific instantion.
delete_breakpoints
gdb_test "break 'void foo<int>(int)'" ".*" \
    "instantiation: set breakpoint"


gdb_run_cmd
gdb_expect {
    -re ".*Breakpoint \[0-9\]+,.*foo<int> \\(i=0\\).*$gdb_prompt $" {
	pass "instantiation: run to breakpoint"
    }
    -re "$gdb_prompt $" {
	fail "instantiation: run to breakpoint"
    }
    timeout {
	fail "instantiation: run to breakpoint (timeout)"
    }
}

gdb_test "continue" \
    ".*Breakpoint.*foo<int> \\(i=1\\).*" \
    "instantiation: run to breakpoint 2"


# Make sure we can set a breakpoint on a source statement that spans
# multiple lines.

delete_breakpoints

set bp_location [gdb_get_line_number "set multi-line breakpoint here"]

if { ![runto_main] } {
    fail "Can't run to main for multi_line_foo tests."
    return 0
}

gdb_test "break $srcfile:$bp_location" \
    "Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
    "set multi_line_foo breakpoint"
gdb_test "continue" \
    ".*Breakpoint.*multi_line_foo<int> \\(i=0\\).*" \
    "run to multi_line_foo breakpoint 2 <int>"
gdb_test "continue" \
    ".*Breakpoint.*multi_line_foo<double> \\(i=0\\).*" \
    "run to multi_line_foo breakpoint 2 <double>"
