# Copyright 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/>.

if { [skip_cplus_tests] } { continue }

load_lib mi-support.exp
set MIFLAGS "-i=mi"

gdb_exit
if [mi_gdb_start] {
    continue
}

standard_testfile .cc
set opts {debug c++}

if [build_executable $testfile.exp $testfile $srcfile $opts] {
    return -1;
}

mi_gdb_load ${binfile}

mi_prepare_inline_tests $srcfile

# Enable using RTTI to determine real types of the objects
proc set_print_object {state testname} {
    mi_gdb_test "-interpreter-exec console \"set print object ${state}\"" \
        {\^done} \
        "-interpreter-exec console \"set print object ${state}\" in $testname"
}

proc check_derived_children_without_rtti {varobj_name var_name testname} {
    mi_list_varobj_children ${varobj_name} "
        { ${varobj_name}.public public 1 }
    " "list children of ${var_name} (without RTTI) in $testname"
    mi_list_varobj_children "${varobj_name}.public" "
        { ${varobj_name}.public.A A 0 int }
    " "list children of ${var_name}.public (without RTTI) in $testname"
}

proc check_derived_content_without_rtti {varobj_name var_name testname} {
    mi_check_varobj_value ${varobj_name}.public.A 1 \
        "check ${var_name}->A (without RTTI) in $testname"
}

proc check_derived_without_rtti {varobj_name var_name testname} {
    check_derived_children_without_rtti ${varobj_name} ${var_name} ${testname}
    check_derived_content_without_rtti ${varobj_name} ${var_name} ${testname}
}

proc check_new_derived_without_rtti {var_name var_type testname} {
    set varobj_name VAR
    mi_create_varobj_checked ${varobj_name} ${var_name} ${var_type} \
        "create varobj for ${var_name} (without RTTI) in ${testname}"
    check_derived_without_rtti ${varobj_name} ${var_name} ${testname}
    mi_delete_varobj ${varobj_name} \
        "delete varobj for ${var_name} (without RTTI) in ${testname}"
}

proc check_derived_children_with_rtti {varobj_name var_name testname} {
    mi_list_varobj_children ${varobj_name} "
        { ${varobj_name}.Base Base 1 Base }
        { ${varobj_name}.public public 2 }
    " "list children of ${var_name} (with RTTI) in $testname"
    mi_list_varobj_children "${varobj_name}.Base" "
        { ${varobj_name}.Base.public public 1 }
    " "list children of ${var_name}.Base (with RTTI) in $testname"
    mi_list_varobj_children "${varobj_name}.Base.public" "
        { ${varobj_name}.Base.public.A A 0 int }
    " "list children of ${var_name}.Base.public (with RTTI) in $testname"
    mi_list_varobj_children "${varobj_name}.public" "
        { ${varobj_name}.public.B B 0 int }
        { ${varobj_name}.public.C C 0 int }
    " "list children of ${var_name}.public (with RTTI) in $testname"
}

proc check_derived_content_with_rtti {varobj_name var_name testname} {
    mi_check_varobj_value ${varobj_name}.Base.public.A 1 \
        "check ${var_name}->A (with RTTI) in $testname"
    mi_check_varobj_value ${varobj_name}.public.B 2 \
        "check ${var_name}->B (with RTTI) in $testname"
    mi_check_varobj_value ${varobj_name}.public.C 3 \
        "check ${var_name}->C (with RTTI) in $testname"
}

proc check_derived_with_rtti {varobj_name var_name testname} {
    check_derived_children_with_rtti ${varobj_name} ${var_name} $testname
    check_derived_content_with_rtti ${varobj_name} ${var_name} $testname
}

proc check_new_derived_with_rtti {var_name var_type testname} {
    set varobj_name VAR
    mi_create_varobj_checked ${varobj_name} ${var_name} ${var_type} \
        "create varobj for ${var_name} (with RTTI) in $testname"
    check_derived_with_rtti ${varobj_name} ${var_name} $testname
    mi_delete_varobj ${varobj_name} \
        "delete varobj for ${var_name} (with RTTI) in $testname"
}

mi_run_inline_test use_rtti_for_ptr
mi_run_inline_test use_rtti_for_ref
mi_run_inline_test use_rtti_for_ptr_child
mi_run_inline_test use_rtti_for_ref_child
mi_run_inline_test use_rtti_with_multiple_inheritence
# mi_run_inline_test type_update_when_use_rtti
mi_run_inline_test skip_type_update_when_not_use_rtti

mi_gdb_exit
return 0
