# Copyright 2006-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

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

if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != ""} {
  untested $testfile.exp
  return -1
}

mi_gdb_load ${binfile}

mi_prepare_inline_tests $srcfile

mi_run_inline_test reference_update
mi_run_inline_test base_in_reference
mi_run_inline_test reference_to_pointer
mi_run_inline_test reference_to_struct
mi_run_inline_test path_expression

set lineno [gdb_get_line_number "/* anonymous_structs_and_unions */"]
mi_create_breakpoint \
    "$srcfile:$lineno" {[0-9]+} keep {anonymous_structs_and_unions\(\)} \
    ".*mi-var-cp.cc" $lineno $hex "break in anonymous_structs_and_unions"
mi_execute_to "exec-continue" "breakpoint-hit" \
    "anonymous_structs_and_unions" "" ".*" ".*" {"" "disp=\"keep\""} \
    "continue to anonymous_structs breakpoint"

set tree {
  Anonymous a {
    {} public {
      anonymous struct {
        {} public {
          int b {}
        }
      }
      anonymous struct {
        {} public {
          int c {}
        }
      }
      anonymous struct {
        {} public {
          int d {}
          anonymous struct {
            {} public {
              int e {}
              anonymous struct {
                {} public {
                  int f {}
                  anonymous union {
                    {} public {
                      int g {}
                      char h {}
                    }
                  }
                }
              }
	      anonymous union {
		{} public {
		  int i {}
		  char j {}
		}
	      }
	    }
	  }
	}
      }
    }
  }
}

proc verify_everything {variable_name} {
  # Test -var-list-children
  mi_varobj_tree_test_children_callback $variable_name

  # Bring the variable named by VARIABLE_NAME into the current scope
  # in VAROBJ.
  upvar #0 $variable_name varobj

  # Test -var-info-path-expression
  mi_gdb_test "-var-info-path-expression $varobj(obj_name)" \
      "\\^done,path_expr=\"[string_to_regexp $varobj(path_expr)]\"" \
      "path expression for $varobj(obj_name)"

  # Test -var-info-expression
  mi_gdb_test "-var-info-expression $varobj(obj_name)" \
      "\\^done,lang=\"C\\+\\+\",exp=\"[string_to_regexp $varobj(display_name)]\"" \
      "expression for $varobj(obj_name)"
}

mi_walk_varobj_tree c++ $tree verify_everything

mi_gdb_exit
return 0
