diff options
author | Keith Seitz <keiths@redhat.com> | 2018-08-29 15:12:24 -0700 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2018-08-29 15:12:24 -0700 |
commit | 078a020797210f4d8f9491bbfe16ec31e9efb652 (patch) | |
tree | 278f541a2e88d33fcc3c4f782b5265a477abb540 /gdb/testsuite/lib | |
parent | fcaad03cc027ec2cdf7f2cff70d792867d43c57f (diff) | |
download | gdb-078a020797210f4d8f9491bbfe16ec31e9efb652.zip gdb-078a020797210f4d8f9491bbfe16ec31e9efb652.tar.gz gdb-078a020797210f4d8f9491bbfe16ec31e9efb652.tar.bz2 |
C++ compile support
This patch adds *basic* support for C++ to the compile feature. It does
most simple type conversions, including everything that C compile does and
your basic "with-classes" type of C++.
I've written a new compile-support.exp support file which adds a new test
facility for automating and simplifying "compile print" vs "compile code"
testing. See testsuite/lib/compile-support.exp and CompileExpression
for more on that. The tests use this facility extensively.
This initial support has several glaring omissions:
- No template support at all
I have follow-on patches for this, but they add much complexity
to this "basic" support. Consequently, they will be submitted separately.
- Cannot print functions
The code template needs tweaking, and I simply haven't gotten to it yet.
- So-called "special function" support is not included
Using constructors, destructors, operators, etc will not work. I have
follow-on patches for that, but they require some work because of the
recent churn in symbol searching.
- There are several test suite references to "compile/1234" bugs.
I will file bugs and update the test suite's bug references before pushing
these patches.
The test suite started as a copy of the original C-language support, but
I have written tests to exercise the basic functionality of the plug-in.
I've added a new option for outputting debug messages for C++ type-conversion
("debug compile-cplus-types").
gdb/ChangeLog:
* Makefile.in (SUBDIR_GCC_COMPILE_SRCS): Add compile-cplus-symbols.c
and compile-cplus-types.c.
(HFILES_NO_SRCDIR): Add gcc-cp-plugin.h.
* c-lang.c (cplus_language_defn): Set C++ compile functions.
* c-lang.h (cplus_get_compile_context, cplus_compute_program):
Declare.
* compile/compile-c-support.c: Include compile-cplus.h.
(load_libcompile): Templatize.
(get_compile_context): "New" function.
(c_get_compile_context): Use get_compile_context.
(cplus_get_compile_context): New function.
(cplus_push_user_expression, cplus_pop_user_expression)
(cplus_add_code_header, cplus_add_input, cplus_compile_program)
(cplus_compute_program): Define new structs/functions.
* compile/compile-cplus-symmbols.c: New file.
* compile/compile-cplus-types.c: New file.
* compile/compile-cplus.h: New file.
* compile/compile-internal.h (debug_compile_oracle, GCC_TYPE_NONE):
Declare.
* compile/compile-object-load.c (get_out_value_type): Use
strncmp_iw when comparing symbol names.
(compile_object_load): Add mst_bss and mst_data.
* compile/compile.c (_initialize_compile): Remove
-Wno-implicit-function-declaration from `compile_args'.
* compile/gcc-cp-plugin.h: New file.
* NEWS: Mention C++ compile support and new debug options.
gdb/testsuite/ChangeLog:
* gdb.compile/compile-cplus-anonymous.cc: New file.
* gdb.compile/compile-cplus-anonymous.exp: New file.
* gdb.compile/compile-cplus-array-decay.cc: New file.
* gdb.compile/compile-cplus-array-decay.exp: New file.
* gdb.compile/compile-cplus-inherit.cc: New file.
* gdb.compile/compile-cplus-inherit.exp: New file.
* gdb.compile/compile-cplus-member.cc: New file.
* gdb.compile/compile-cplus-member.exp: New file.
* gdb.compile/compile-cplus-method.cc: New file.
* gdb.compile/compile-cplus-method.exp: New file.
* gdb.compile/compile-cplus-mod.c: "New" file.
* gdb.compile/compile-cplus-namespace.cc: New file.
* gdb.compile/compile-cplus-namespace.exp: New file.
* gdb.compile/compile-cplus-nested.cc: New file.
* gdb.compile/compile-cplus-nested.exp: New file.
* gdb.compile/compile-cplus-print.c: "New" file.
* gdb.compile/compile-cplus-print.exp: "New" file.
* gdb.compile/compile-cplus-virtual.cc: New file.
* gdb.compile/compile-cplus-virtual.exp: New file.
* gdb.compile/compile-cplus.c: "New" file.
* gdb.compile/compile-cplus.exp: "New" file.
* lib/compile-support.exp: New file.
doc/ChangeLog:
* gdb.texinfo (Compiling and injecting code in GDB): Document
set/show "compile-oracle" and "compile-cplus-types" commands.
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r-- | gdb/testsuite/lib/compile-support.exp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/gdb/testsuite/lib/compile-support.exp b/gdb/testsuite/lib/compile-support.exp new file mode 100644 index 0000000..b784c35 --- /dev/null +++ b/gdb/testsuite/lib/compile-support.exp @@ -0,0 +1,227 @@ +# Copyright 2015-2018 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/>. + +# Generic/oft used support routines for testing GDB's compile feature. + +# Return 1 if we should skip tests of the "compile" feature. +# This must be invoked after the inferior has been started. + +proc skip_compile_feature_tests {} { + global gdb_prompt + + set result 0 + gdb_test_multiple "compile code -- ;" "check for working compile command" { + "Could not load libcc1.*\r\n$gdb_prompt $" { + set result 1 + } + -re "Command not supported on this host\\..*\r\n$gdb_prompt $" { + set result 1 + } + -re "\r\n$gdb_prompt $" { + } + } + return $result +} + +# This namespace provides some convenience functions for running +# "compile code" and "compile print" tests. +# +# Exported functions are defined inline below. +# +# General usage: +# +# Start a new session, noting that the variable "var" will be used for +# "compile code" expressions. This variable /must/ exist in the stopped +# location. +# +# CompileExpression::new "var" +# +# Test the implicit expression "foo;" with result/value 3. +# CompileExpression::test "foo" 3 +# ---> Runs the following tests (name of tests ignored for illustration) +# gdb_test_no_output "compile code var = foo" +# gdb_test "p var" "= 3" +# gdb_test "compile print foo;" "= 3" +# +# Test the explicit expression "a = function (3); var = a;" with the result 21. +# CompileExpression::test "a = function (3); var = a;" 21 -explicit +# ---> Runs the following tests (name of tests ignored for illustration) +# gdb_test_no_output "compile code a = function (3); var = a;" +# gdb_test "p var" "= 21" +# +# Additional option flags may be passed to test to control the behavior +# of the test harness: +# +# Pass -explicit to specify that the test uses an explicit expression, +# one which sets the value of the variable (see above). Only the code test +# will be run. +# +# Pass -value and/or -print to indicate that the value and/or print steps +# will optionally fail. Specify "xfail" or "kfail" to indicate how +# particular step will fail. These may be followed by any accepted DejaGNU +# parameters such as architecture and bug#. [See examples below.] +# +# To specify that the compile (and consequently print and value tests) is +# expected to kfail/xfail, use -kfail or -xfail with any appropriate +# DejaGNU parameters. Both options override -print and -value. +# [-xfail is given precedence over -kfail should both be given.] +# +# -value is used when a "code" test is run, specifying that the "compile +# code" and "print VAR" steps will fail in the prescribed manner. +# [If the print step generates a PASS, the test is considered invalidly +# written. VAR's value should /always/ be invalidated before a test is +# run.] +# +# -print is used to specify that an expression will fail in the prescribed +# manner when "print" test is executed. +# +# Pass "-name NAME" to set an optional test name. If not specified, +# the harness will use test names such as "compile code EXPR" and +# "result of compile code EXPR". +# +# Pass "-noprint" or "-nocode" to suppress print or code tests, respectively, +# This is useful when the expression being tested modifies the object +# being tested, e.g., "a++". +# +# These options must be passed LAST to CompileExpression::test. +# +# Examples: +# +# Both "code" and "print" tests are expected to xfail: +# CompileExpression add_imp "foo" 3 -compile {xfail *-*-*} -print {xfail *-*-*} +# +# The "print $VARIABLE" portion of the "code" test is expected to kfail +# (the actual "compile code" GDB command will succeed), but the "print" +# test should pass: +# CompileExpression add_imp "foo" 3 -value {kfail *-*-* gdb/1234} + +namespace eval ::CompileExpression { + + # The variable name to check testing results. This variable + # must be in scope when tests are run. + variable varName_ {} + + # Start a new expression list. VARNAME is the name of the variable + # that will be printed to check if the result of the test was + # successful. + proc new {varname} { + variable varName_ + + set varName_ $varname + } + + # Test an expression. + # + # See the preamble for a list of valid optional arguments. + # + # Implicit expressions will be sent to GDB in the form + # "$varName = $EXP". "p $varName" will be used to decide the pass + # or fail status of the test. + # + # Explicit expressions will be sent to GDB as-is and tested using only + # "compile code". The expression should set the value of the variable + # $varName, which is then printed to determine whether the test passed + # or failed. + # + # Unlike explicit expressions, implicit expressions are tested with both + # "compile print" and "compile code". + + proc test {exp result args} { + parse_args {{value {"" ""}} {print {"" ""}} {name ""} + {noprint} {nocode} {explicit} {xfail {"" ""}} {kfail {"" ""}}} + + if {[lindex $xfail 0] != ""} { + set l "xfail $xfail" + } elseif {[lindex $kfail 0] != ""} { + set l "kfail $kfail" + } else { + set l "" + set compile {"" ""} + } + if {$l != ""} { + set compile $l + set print $l + set value $l + } + + if {!$nocode} { + do_test_ code $exp $result $explicit $name \ + [list $compile $value $print] + } + if {!$noprint} { + do_test_ print $exp $result $explicit $name \ + [list $compile $value $print] + } + } + + # Run a compile test for CMD ("print" or "code"). + + proc do_test_ {cmd exp result is_explicit tst fail_list} { + variable varName_ + + if {![string match $cmd "code"] + && ![string match $cmd "print"]} { + error "invalid command, $cmd; should be \"print\" or \"compile\"" + } + + # Get expected result of test. Will be "" if test is + # expected to PASS. + lassign $fail_list fail_compile fail_value fail_print + + # Set a test name if one hasn't been provided. + if {$tst == ""} { + set tst "compile $cmd $exp" + } + + if {[string match $cmd "print"]} { + if {!$is_explicit} { + eval setup_failures_ $fail_print + gdb_test "compile print $exp" $result $tst + } + } else { + if {$is_explicit} { + set command "compile code $exp" + } else { + set command "compile code $varName_ = $exp" + } + eval setup_failures_ $fail_compile + gdb_test_no_output $command $tst + eval setup_failures_ $fail_value + gdb_test "p $varName_" "= $result" "result of $tst" + } + } + + # A convenience proc used to set up xfail and kfail tests. + # HOW is either xfail or kfail (case is ignored). ARGS is any + # optional architecture, bug number, or other string to pass to + # respective DejaGNU setup_$how routines. + + proc setup_failures_ {how args} { + switch -nocase $how { + xfail { + eval setup_xfail $args + } + + kfail { + eval setup_kfail $args + } + + default { + # Do nothing. Either the test is expected to PASS + # or we have an unhandled failure mode. + } + } + } +} |