Index: testsuite/gdb.cp/cpexprs.exp
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.exp
diff -N testsuite/gdb.cp/cpexprs.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.exp 28 Jan 2010 22:55:52 -0000
@@ -0,0 +1,724 @@
+# cpexprs.exp - C++ expressions tests
+#
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+#
+# Contributed by Red Hat, originally written by Keith Seitz.
+#
+# 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 .
+
+# This file is part of the gdb testsuite.
+
+# A helper proc which sets a breakpoint at FUNC and attempts to
+# run to the breakpoint.
+proc test_breakpoint {func} {
+ global DEC
+
+ # Restart every time
+ if {![runto_main]} {
+ perror "could not run to main when attempting to break at $func"
+ } else {
+ gdb_breakpoint "$func"
+ set i [expr {[string last : $func] + 1}]
+ set efunc [string_to_regexp [string range $func $i end]]
+ gdb_test "continue" \
+ "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
+ "continue to $func"
+ }
+}
+
+# Add a function to the list of tested functions
+# FUNC is the name of the function (which will be passed to gdb commands)
+# TYPE is the type of the function, as expected from the "print" command
+# PRINT is the name of the function, as expected result of the print command
+# *OR* "-", indicating that FUNC should be used (needed for virtual/inherited
+# funcs)
+# LST is either the expected result of the list command (the comment from
+# the source code) *OR* "-", in which case FUNC will be used
+#
+# Usage:
+# add NAME TYPE PRINT LST
+# add NAME TYPE PRINT -
+proc add {func type print lst} {
+ global all_functions CONVAR ADDR
+
+ set all_functions($func,type) $type
+ if {$print == "-"} {
+ set print $func
+ }
+
+ # An exception: since gdb canonicalizes C++ output,
+ # "(void)" must be mutated to "()".
+ regsub {\(void\)} $print {()} print
+
+ set all_functions($func,print) \
+ "$CONVAR = {[string_to_regexp $type]} $ADDR <[string_to_regexp $print].*>"
+ if {$lst == "-"} {
+ set lst "$func"
+ }
+ set all_functions($func,list) ".*// [string_to_regexp $lst]"
+}
+
+proc get {func cmd} {
+ global all_functions
+ return $all_functions($func,$cmd)
+}
+
+# Returns a list of function names for a given command
+proc get_functions {cmd} {
+ global all_functions
+ set result {}
+ foreach i [array names all_functions *,$cmd] {
+ if {$all_functions($i) != ""} {
+ set idx [string last , $i]
+ if {$idx != -1} {
+ lappend result [string range $i 0 [expr {$idx - 1}]]
+ }
+ }
+ }
+
+ return [lsort $result]
+}
+
+# Some convenience variables for this test
+set DEC {[0-9]}; # a decimal number
+set HEX {[0-9a-fA-F]}; # a hexidecimal number
+set CONVAR "\\\$$DEC+"; # convenience variable regexp
+set ADDR "0x$HEX+"; # address
+
+# An array of functions/methods that we are testing...
+# Each element consists is indexed by NAME,COMMAND, where
+# NAME is the function name and COMMAND is the gdb command that
+# we are testing. The value of the array for any index pair is
+# the expected result of running COMMAND with the NAME as argument.
+
+# The array holding all functions/methods to test. Valid subindexes
+# are (none need character escaping -- "add" will take care of that):
+
+# add name type print_name list
+# NAME,type: value is type of function
+# NAME,print: value is print name of function (careful w/inherited/virtual!)
+# NAME,list: value is comment in source code on first line of function
+# (without the leading "//")
+array set all_functions {}
+
+# "Normal" functions/methods
+add {main} \
+ {int (int, char **)} \
+ - \
+ -
+add {derived::a_function} \
+ {void (const derived * const)} \
+ - \
+ -
+add {base1::a_function} \
+ {void (const base1 * const)} \
+ - \
+ -
+add {base2::a_function} \
+ {void (const base2 * const)} \
+ - \
+ -
+
+# Constructors
+
+# On targets using the ARM EABI, the constructor is expected to return
+# "this".
+proc ctor { type arglist } {
+ if { [istarget arm*-*eabi*] } {
+ set ret "$type *"
+ } else {
+ set ret "void "
+ }
+ if { $arglist != "" } {
+ set arglist ", $arglist"
+ }
+ return "${ret}($type * const$arglist)"
+}
+
+add {derived::derived} \
+ [ctor derived ""] \
+ - \
+ -
+add {base1::base1(void)} \
+ [ctor base1 "const void ** const"] \
+ - \
+ -
+add {base1::base1(int)} \
+ [ctor base1 "int"] \
+ - \
+ -
+add {base2::base2} \
+ [ctor base2 "const void ** const"] \
+ - \
+ -
+add {base::base(void)} \
+ [ctor base ""] \
+ - \
+ -
+add {base::base(int)} \
+ [ctor base "int"] \
+ - \
+ -
+
+# Destructors
+
+# On targets using the ARM EABI, some destructors are expected
+# to return "this". Others are void. For internal reasons,
+# GCC returns void * instead of $type *; RealView appears to do
+# the same.
+proc dtor { type } {
+ if { [istarget arm*-*eabi*] } {
+ set ret "void *"
+ } else {
+ set ret "void "
+ }
+ return "${ret}($type * const)"
+}
+
+add {base::~base} \
+ [dtor base] \
+ - \
+ -
+
+# Overloaded methods (all are const -- we try to use the void
+# method with and without specifying "const")
+add {base::overload(void)} \
+ {int (const base * const)} \
+ - \
+ {base::overload(void) const}
+add {base::overload(void) const} \
+ {int (const base * const)} \
+ - \
+ {base::overload(void) const}
+add {base::overload(int) const} \
+ {int (const base * const, int)} \
+ - \
+ -
+add {base::overload(short) const} \
+ {int (const base * const, short)} \
+ - \
+ -
+add {base::overload(long) const} \
+ {int (const base * const, long)} \
+ - \
+ -
+add {base::overload(char*) const} \
+ {int (const base * const, char *)} \
+ - \
+ -
+add {base::overload(base&) const} \
+ {int (const base * const, base &)} \
+ - \
+ -
+
+# Operators
+add {base::operator+} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator++} \
+ {base (base * const)} \
+ - \
+ -
+add {base::operator+=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator-} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator--} \
+ {base (base * const)} \
+ - \
+ -
+add {base::operator-=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator*} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator*=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator/} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator/=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator%} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator%=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator<} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator<=} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator>} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator>=} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator!=} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator==} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator!} \
+ {bool (const base * const)} \
+ - \
+ -
+add {base::operator&&} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator||} \
+ {bool (const base * const, const base &)} \
+ - \
+ -
+add {base::operator<<} \
+ {int (const base * const, int)} \
+ - \
+ -
+add {base::operator<<=} \
+ {base (base * const, int)} \
+ - \
+ -
+add {base::operator>>} \
+ {int (const base * const, int)} \
+ - \
+ -
+add {base::operator>>=} \
+ {base (base * const, int)} \
+ - \
+ -
+add {base::operator~} \
+ {int (const base * const)} \
+ - \
+ -
+add {base::operator&} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator&=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator|} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator|=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator^} \
+ {int (const base * const, const base &)} \
+ - \
+ -
+add {base::operator^=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator=} \
+ {base (base * const, const base &)} \
+ - \
+ -
+add {base::operator()} \
+ {void (const base * const)} \
+ - \
+ -
+add {base::operator[]} \
+ {int (const base * const, int)} \
+ - \
+ -
+add {base::operator new} \
+ {void *(size_t)} \
+ - \
+ -
+add {base::operator delete} \
+ {void (void *)} \
+ - \
+ -
+add {base::operator new[]} \
+ {void *(size_t)} \
+ - \
+ -
+add {base::operator delete[]} \
+ {void (void *)} \
+ - \
+ -
+add {base::operator char*} \
+ {char *(const base * const)} \
+ - \
+ -
+add {base::operator fluff*} \
+ {fluff *(const base * const)} \
+ - \
+ -
+add {base::operator fluff**} \
+ {fluff **(const base * const)} \
+ - \
+ -
+add {base::operator int} \
+ {int (const base * const)} \
+ - \
+ -
+
+# Templates
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ -
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ -
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ -
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ -
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ -
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {flubber} \
+ {void (void)} \
+ - \
+ flubber
+add {tclass::do_something} \
+ {void (tclass * const)} \
+ - \
+ {tclass::do_something}
+add {policy1::policy} \
+ [ctor "policy >" "int"] \
+ {policy >::policy} \
+ {policy::policy}
+add {policy2::policy} \
+ [ctor "policy >" int] \
+ {policy >::policy} \
+ {policy::policy}
+add {policy3::policy} \
+ [ctor "policy >" "int"] \
+ {policy >::policy} \
+ {policy::policy}
+add {policy4::policy} \
+ [ctor "policy >" "int"] \
+ {policy >::policy} \
+ {policy::policy}
+add {policy1::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policy2::function} \
+ {void (void)} \
+ {operation_2::function} \
+ {operation_2::function}
+add {policy3::function} \
+ {void (void)} \
+ {operation_3::function} \
+ {operation_3::function}
+add {policy4::function} \
+ {void (void)} \
+ {operation_4::function} \
+ {operation_4::function}
+add {policyd >::policyd} \
+ [ctor "policyd >" "int"] \
+ - \
+ {policyd::policyd}
+add {policyd1::policyd} \
+ [ctor "policyd >" "int"] \
+ {policyd >::policyd} \
+ {policyd::policyd}
+add {policyd >::~policyd} \
+ [dtor "policyd >"] \
+ - \
+ {policyd::~policyd}
+add {policyd1::~policyd} \
+ [dtor "policyd >"] \
+ {policyd >::~policyd} \
+ {policyd::~policyd}
+add {policyd >::policyd} \
+ [ctor "policyd >" "long"] \
+ - \
+ {policyd::policyd}
+add {policyd2::policyd} \
+ [ctor "policyd >" "long"] \
+ {policyd >::policyd} \
+ {policyd::policyd}
+add {policyd >::~policyd} \
+ [dtor "policyd >"] \
+ - \
+ {policyd::~policyd}
+add {policyd2::~policyd} \
+ [dtor "policyd >"] \
+ {policyd >::~policyd} \
+ {policyd::~policyd}
+add {policyd >::policyd} \
+ [ctor "policyd >" "char"] \
+ - \
+ {policyd::policyd}
+add {policyd3::policyd} \
+ [ctor "policyd >" "char"] \
+ {policyd >::policyd} \
+ {policyd::policyd}
+add {policyd >::~policyd} \
+ [dtor "policyd >"] \
+ - \
+ {policyd::~policyd}
+add {policyd3::~policyd} \
+ [dtor "policyd >"] \
+ {policyd >::~policyd} \
+ {policyd::~policyd}
+add {policyd >::policyd} \
+ [ctor "policyd >" "base"] \
+ - \
+ {policyd::policyd}
+add {policyd4::policyd} \
+ [ctor "policyd >" "base"] \
+ {policyd >::policyd} \
+ {policyd::policyd}
+add {policyd >::~policyd} \
+ [dtor "policyd >"] \
+ - \
+ {policyd::~policyd}
+add {policyd4::~policyd} \
+ [dtor "policyd >"] \
+ {policyd >::~policyd} \
+ {policyd::~policyd}
+add {policyd, operation_1 > >::policyd} \
+ [ctor "policyd, operation_1 > >" "tclass"] \
+ - \
+ {policyd::policyd}
+add {policyd5::policyd} \
+ [ctor "policyd, operation_1 > >" "tclass"] \
+ {policyd, operation_1 > >::policyd} \
+ {policyd::policyd}
+add {policyd, operation_1 > >::~policyd} \
+ [dtor "policyd, operation_1 > >"] \
+ - \
+ {policyd::~policyd}
+add {policyd5::~policyd} \
+ [dtor "policyd, operation_1 > >"] \
+ {policyd, operation_1 > >::~policyd} \
+ {policyd::~policyd}
+add {policyd >::function} \
+ {void (void)} \
+ {operation_1::function}\
+ {operation_1::function}
+add {policyd1::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd2::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd >::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd3::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd >::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd4::function} \
+ {void (void)} \
+ {operation_1::function} \
+ {operation_1::function}
+add {policyd, operation_1 > >::function} \
+ {void (void)} \
+ {operation_1 >::function} \
+ {operation_1::function}
+add {policyd5::function} \
+ {void (void)} \
+ {operation_1 >::function} \
+ {operation_1::function}
+
+# Start the test
+if {$tracelevel} {
+ strace $tracelevel
+}
+
+if {[skip_cplus_tests]} { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "cpexprs"
+set srcfile "${testfile}.cc"
+set binfile [file join $objdir $subdir $testfile]
+
+if {[gdb_compile [file join $srcdir $subdir $srcfile] $binfile \
+ executable {debug c++}] != "" } {
+ untested "$testfile.exp"
+ return -1
+}
+
+if {[get_compiler_info $binfile "c++"]} {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir [file join $srcdir $subdir]
+gdb_load $binfile
+
+if {![runto_main]} {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Set the listsize to one. This will help with testing "list".
+gdb_test "set listsize 1"
+
+# "print METHOD"
+foreach name [get_functions print] {
+ gdb_test "print $name" [get $name print] "print $name"
+}
+
+# "list METHOD"
+foreach name [get_functions list] {
+ gdb_test "list $name" [get $name list] "list $name"
+}
+
+# Running to breakpoint -- use any function we can "list"
+foreach name [get_functions list] {
+ # Skip "main", since test_breakpoint uses it
+ if {[string compare $name "main"] != 0} {
+ test_breakpoint $name
+ }
+}
+
+gdb_exit
+return 0
Index: testsuite/gdb.cp/cpexprs.cc
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.cc
diff -N testsuite/gdb.cp/cpexprs.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.cc 28 Jan 2010 22:55:55 -0000
@@ -0,0 +1,431 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Contributed by Red Hat, originally written by Keith Seitz.
+
+ 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 .
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org */
+
+#include
+#include
+
+// Forward decls
+class base;
+class derived;
+
+// A simple template with specializations
+template
+class tclass
+{
+public:
+ void do_something () { } // tclass::do_something
+};
+
+template <>
+void tclass::do_something () { } // tclass::do_something
+
+template <>
+void tclass::do_something () { } // tclass::do_something
+
+template<>
+void tclass::do_something () { } // tclass::do_something
+
+template<>
+void tclass::do_something () { } // tclass::do_something
+
+// A simple template with multiple template parameters
+template
+void flubber (void) // flubber
+{
+ A a;
+ B b;
+ C c;
+ D d;
+ E e;
+
+ ++a;
+ ++b;
+ ++c;
+ ++d;
+ ++e;
+}
+
+// Some contrived policies
+template
+struct operation_1
+{
+ static void function (void) { } // operation_1::function
+};
+
+template
+struct operation_2
+{
+ static void function (void) { } // operation_2::function
+};
+
+template
+struct operation_3
+{
+ static void function (void) { } // operation_3::function
+};
+
+template
+struct operation_4
+{
+ static void function (void) { } // operation_4::function
+};
+
+// A policy-based class w/ and w/o default policy
+template
+class policy : public Policy
+{
+public:
+ policy (T obj) : obj_ (obj) { } // policy::policy
+
+private:
+ T obj_;
+};
+
+template >
+class policyd : public Policy
+{
+public:
+ policyd (T obj) : obj_ (obj) { } // policyd::policyd
+ ~policyd (void) { } // policyd::~policyd
+
+private:
+ T obj_;
+};
+
+typedef policy > policy1;
+typedef policy > policy2;
+typedef policy > policy3;
+typedef policy > policy4;
+
+typedef policyd policyd1;
+typedef policyd policyd2;
+typedef policyd policyd3;
+typedef policyd policyd4;
+typedef policyd > policyd5;
+
+class fluff { };
+static fluff *g_fluff = new fluff ();
+
+class base
+{
+protected:
+ int foo_;
+
+public:
+ base (void) : foo_ (42) { } // base::base(void)
+ base (int foo) : foo_ (foo) { } // base::base(int)
+ ~base (void) { } // base::~base
+
+ // Some overloaded methods
+ int overload (void) const { return 0; } // base::overload(void) const
+ int overload (int i) const { return 1; } // base::overload(int) const
+ int overload (short s) const { return 2; } // base::overload(short) const
+ int overload (long l) const { return 3; } // base::overload(long) const
+ int overload (char* a) const { return 4; } // base::overload(char*) const
+ int overload (base& b) const { return 5; } // base::overload(base&) const
+
+ // Operators
+ int operator+ (base const& o) const // base::operator+
+ { return foo_ + o.foo_; }
+
+ base operator++ (void) // base::operator++
+ { ++foo_; return *this; }
+
+ base operator+=(base const& o) // base::operator+=
+ { foo_ += o.foo_; return *this; }
+
+ int operator- (base const& o) const // base::operator-
+ { return foo_ - o.foo_; }
+
+ base operator-- (void) // base::operator--
+ { --foo_; return *this; }
+
+ base operator-= (base const& o) // base::operator-=
+ { foo_ -= o.foo_; return *this; }
+
+ int operator* (base const& o) const // base::operator*
+ { return foo_ * o.foo_; }
+
+ base operator*= (base const& o) // base::operator*=
+ { foo_ *= o.foo_; return *this; }
+
+ int operator/ (base const& o) const // base::operator/
+ { return foo_ / o.foo_; }
+
+ base operator/= (base const& o) // base::operator/=
+ { foo_ /= o.foo_; return *this; }
+
+ int operator% (base const& o) const // base::operator%
+ { return foo_ % o.foo_; }
+
+ base operator%= (base const& o) // base::operator%=
+ { foo_ %= o.foo_; return *this; }
+
+ bool operator< (base const& o) const // base::operator<
+ { return foo_ < o.foo_; }
+
+ bool operator<= (base const& o) const // base::operator<=
+ { return foo_ <= o.foo_; }
+
+ bool operator> (base const& o) const // base::operator>
+ { return foo_ > o.foo_; }
+
+ bool operator>= (base const& o) const // base::operator>=
+ { return foo_ >= o.foo_; }
+
+ bool operator!= (base const& o) const // base::operator!=
+ { return foo_ != o.foo_; }
+
+ bool operator== (base const& o) const // base::operator==
+ { return foo_ == o.foo_; }
+
+ bool operator! (void) const // base::operator!
+ { return !foo_; }
+
+ bool operator&& (base const& o) const // base::operator&&
+ { return foo_ && o.foo_; }
+
+ bool operator|| (base const& o) const // base::operator||
+ { return foo_ || o.foo_; }
+
+ int operator<< (int value) const // base::operator<<
+ { return foo_ << value; }
+
+ base operator<<= (int value) // base::operator<<=
+ { foo_ <<= value; return *this; }
+
+ int operator>> (int value) const // base::operator>>
+ { return foo_ >> value; }
+
+ base operator>>= (int value) // base::operator>>=
+ { foo_ >>= value; return *this; }
+
+ int operator~ (void) const // base::operator~
+ { return ~foo_; }
+
+ int operator& (base const& o) const // base::operator&
+ { return foo_ & o.foo_; }
+
+ base operator&= (base const& o) // base::operator&=
+ { foo_ &= o.foo_; return *this; }
+
+ int operator| (base const& o) const // base::operator|
+ { return foo_ | o.foo_; }
+
+ base operator|= (base const& o) // base::operator|=
+ { foo_ |= o.foo_; return *this; }
+
+ int operator^ (base const& o) const // base::operator^
+ { return foo_ ^ o.foo_; }
+
+ base operator^= (base const& o) // base::operator^=
+ { foo_ ^= o.foo_; return *this; }
+
+ base operator= (base const& o) // base::operator=
+ { foo_ = o.foo_; return *this; }
+
+ void operator() (void) const // base::operator()
+ { return; }
+
+ int operator[] (int idx) const // base::operator[]
+ { return idx; }
+
+ void* operator new (size_t size) throw () // base::operator new
+ { return malloc (size); }
+
+ void operator delete (void* ptr) // base::operator delete
+ { free (ptr); }
+
+ void* operator new[] (size_t size) throw () // base::operator new[]
+ { return malloc (size); }
+
+ void operator delete[] (void* ptr) // base::operator delete[]
+ { free (ptr); }
+
+ base const* operator-> (void) const // base::opeartor->
+ { return this; }
+
+ int operator->* (base const& b) const // base::operator->*
+ { return foo_ * b.foo_; }
+
+ operator char* () const { return const_cast ("hello"); } // base::operator char*
+ operator int () const { return 21; } // base::operator int
+ operator fluff* () const { return new fluff (); } // base::operator fluff*
+ operator fluff** () const { return &g_fluff; } // base::operator fluff**
+};
+
+class base1 : public virtual base
+{
+public:
+ base1 (void) : foo_ (21) { } // base1::base1(void)
+ base1 (int a) : foo_(a) { } // base1::base1(int)
+ void a_function (void) const { } // base1::a_function
+
+protected:
+ int foo_;
+};
+
+class base2 : public virtual base
+{
+public:
+ base2 () : foo_ (3) { } // base2::base2
+
+protected:
+ void a_function (void) const { } // base2::a_function
+ int foo_;
+};
+
+class derived : public base1, public base2
+{
+ public:
+ derived(void) : foo_ (4) { } // derived::derived
+ void a_function (void) const // derived::a_function
+ {
+ this->base1::a_function ();
+ this->base2::a_function ();
+ }
+
+ protected:
+ int foo_;
+};
+
+int
+main (int argc, char* argv[]) // main
+{ // main
+ derived d;
+ void (derived::*pfunc) (void) const = &derived::a_function;
+ (d.*pfunc) ();
+
+ base a (1), b (3), c (8);
+ (void) a.overload ();
+ (void) a.overload (static_cast (0));
+ (void) a.overload (static_cast (0));
+ (void) a.overload (static_cast (0));
+ (void) a.overload (static_cast (0));
+ (void) a.overload (a);
+
+ int r;
+ r = b + c;
+ ++a;
+ a += b;
+ r = b - c;
+ --a;
+ a -= b;
+ r = b * c;
+ a *= b;
+ r = b / c;
+ a /= b;
+ r = b % c;
+ a %= b;
+ bool x = (b < c);
+ x = (b <= c);
+ x = (b > c);
+ x = (b >= c);
+ x = (b != c);
+ x = (b == c);
+ x = (!b);
+ x = (b && c);
+ x = (b || c);
+ r = b << 2;
+ a <<= 1;
+ r = b >> 2;
+ a >>= 1;
+ r = ~b;
+ r = b & c;
+ a &= c;
+ r = b | c;
+ a |= c;
+ r = b ^ c;
+ a ^= c;
+ a = c;
+ a ();
+ int i = a[3];
+ derived* f = new derived ();
+ derived* g = new derived[3];
+ delete f;
+ delete[] g;
+ a->overload ();
+ r = a->*b;
+
+ tclass char_tclass;
+ tclass int_tclass;
+ tclass short_tclass;
+ tclass long_tclass;
+ tclass base_tclass;
+ char_tclass.do_something ();
+ int_tclass.do_something ();
+ short_tclass.do_something ();
+ long_tclass.do_something ();
+ base_tclass.do_something ();
+
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+ flubber ();
+
+ policy1 p1 (1);
+ p1.function ();
+ policy2 p2 (2);
+ p2.function ();
+ policy3 p3 (3);
+ p3.function ();
+ policy4 p4 (4);
+ p4.function ();
+
+ policyd1 pd1 (5);
+ pd1.function ();
+ policyd2 pd2 (6);
+ pd2.function ();
+ policyd3 pd3 (7);
+ pd3.function ();
+ policyd4 pd4 (d);
+ pd4.function ();
+ policyd5 pd5 (int_tclass);
+ pd5.function ();
+
+ base1 b1 (3);
+
+ r = a;
+ char* str = a;
+ fluff* flp = a;
+ fluff** flpp = a;
+}
+