Add type-checking and strings to help with debugging

Writing a JIT-compiler is fiddly, and the developer is likely to make
mistakes along the way.

As noted in 994cf9d5f311ff1633e0a9a267cfe6ad60247de3, there was almost no
type-checking within libgccjit - if client code uses the API in such a
way as to request the generation of bogus code, this was likely to violate
assumptions made later on within GCC proper, leading to errors deep inside
GCC e.g. with "internal compiler error", or segmentation faults.

The API will be more developer-friendly if we catch such type errors
at the API boundary (similar to how the other language frontends enforce
these assumptions).

In addition, we should issue good error messages if the client code
misuses the API, so the developer can more easily track down the issues.

The following commit adds type-checking to parts of the API, together
with a way of generating string dumps of the API entities on demand.

The gcc_jit_rvalue type (aka recording::rvalue internally) gains a
type attribute, which is checked at the API boundary in various places
(though this is a work-in-progress: see the TODO.rst file).

In order to generate suitably-descriptive error messages, we need
to be able to "stringify" the entities exposed by the API.

Hence in this commit the various memento objects (such as rvalues, types,
functions, etc) gain an optional m_debug_string attribute.  This string is
non-trivial to generate, via a virtual function call which can lead to
further calls to walk the internal tree of mementos.  Hence it's
lazily generated, and only when an error occurs (or if you want to do
detailed debug logging).  The debug strings are contextual objects, and
hence live for the lifetime of the underlying context.

As an extra quality-of-life benefit, this means that when debugging
libgccjit you can request a stringification of a recording object (although
irritatingly, for some reason on this box when within libgccjit.c I
currently need to cast to the base class to get the debugger to recognize
the method).

For example, when debugging test-quadratic.c:

  (gdb) p ((gcc::jit::recording::memento *)lvalue)->get_debug_string()
  $8 = 0x6a0a70 "q->discriminant"
  (gdb) p ((gcc::jit::recording::memento *)rvalue)->get_debug_string()
  $9 = 0x669b50 "q->b * q->b - (double)4 * q->a * q->c"

With this commit, test-fuzzer.c now runs to completion on this box (albeit
with only 6 of the 200 attempts successfully completing compilation, mostly
due to the randomly-generated code attempting assignments that violate
the type rules).

gcc/jit/

	* TODO.rst: begin a list of error-checking we could do that this
	commit *doesn't* cover.

	* libgccjit.h (gcc_jit_field): Add note that fields can't be
	shared between structs.
	(GCC_JIT_BINARY_OP_MODULO): Fix typo in comment.

	* libgccjit.c: (RETURN_VAL_IF_FAIL_PRINTF2): New.
	(RETURN_VAL_IF_FAIL_PRINTF3): New.
	(RETURN_NULL_IF_FAIL_PRINTF2): New.
	(RETURN_NULL_IF_FAIL_PRINTF3): New.
	(RETURN_IF_FAIL_PRINTF4): New.

	(jit_error): Take a gcc::jit::recording::context rather than
	a gcc_jit_context so that we pass in contexts from the inner
	layer.

	(compatible_types): New, for use in type-checking.

	(gcc_jit_context_new_struct_type): Check each field to ensure that
	it isn't already in use by another struct.

	(gcc_jit_rvalue_dereference_field): Check that ptr is of a pointer
	type and that the field is within the correct struct, using new
	get_debug_string hooks to generate error messages.

	(gcc_jit_rvalue_dereference): Check that rvalue is of a pointer
	type.

	(gcc_jit_function_add_assignment): Use the function's context when
	reporting on NULL lvalue or rvalue.  Verify that the lvalue and
	rvalue have compatible types.

	(gcc_jit_function_add_return): Use the function's context when
	reporting on NULL rvalue.  Verify that the rvalue is of an
	appropriate type given the function's return type.

	* internal-api.h (NUM_GCC_JIT_TYPES): New.
	(gcc::jit::recording::context::record): Move from here to
	internal-api.c.
	(gcc::jit::recording::context::get_opaque_FILE_type): New.
	(gcc::jit::recording::context::m_basic_types): New field.
	(gcc::jit::recording::context::m_FILE_type): New field.

	(gcc::jit::recording::memento::get_debug_string): New method.
	(gcc::jit::recording::memento::memento): Initialize new field
	m_debug_string, and verify context is non-NULL.
	(gcc::jit::recording::memento::make_debug_string): New
	pure-virtual function lazily used by get_debug_string.
	(gcc::jit::recording::memento::m_debug_string): New field, for
	get_debug_string to use as a cache.

	(gcc::jit::recording::string): Rename field m_copy to m_buffer.
	(gcc::jit::recording::from_printf): New factory function.
	(gcc::jit::recording::make_debug_string): New.

	(gcc::jit::recording::location::make_debug_string): New.

	(gcc::jit::recording::type::dereference): New pure-virtual
	function.
	(gcc::jit::recording::type::accepts_writes_from): New virtual
	function.
	(gcc::jit::recording::type::unqualified): New virtual function.

	(gcc::jit::recording::memento_of_get_type::dereference): New.
	(gcc::jit::recording::memento_of_get_type::
	accepts_writes_from): New.
	(gcc::jit::recording::memento_of_get_type::make_debug_string):
	New.

	(gcc::jit::recording::memento_of_get_pointer::make_debug_string):
	New.
	(gcc::jit::recording::memento_of_get_pointer::dereference): New.
	New.

	(gcc::jit::recording::memento_of_get_const::make_debug_string):
	New.
	(gcc::jit::recording::memento_of_get_const::dereference): New.
	New.
	(gcc::jit::recording::memento_of_get_const::accepts_writes_from):
	New.
	(gcc::jit::recording::memento_of_get_const::unqualified): New.

	(gcc::jit::recording::field): New field m_container, for the
	containing struct (or union, if we implement that).
	(gcc::jit::recording::field::get_type): New.
	(gcc::jit::recording::field::get_container): New.
	(gcc::jit::recording::field:set_container): New.
	(gcc::jit::recording::field::make_debug_string): New.

	(gcc::jit::recording::struct_::struct_): Move ctor implementation
	from here into internal-api.c.
	(gcc::jit::recording::struct_::dereference): New.
	(gcc::jit::recording::struct_::make_debug_string): New.

	(gcc::jit::recording::rvalue::m_type): New field.
	(gcc::jit::recording::rvalue::rvalue): Require a non-NULL type for
	new rvalue instances.
	(gcc::jit::recording::rvalue::get_type): New accessor.

	(gcc::jit::recording::lvalue): Eliminate field m_type in favor of
	that within the rvalue base class.

	(gcc::jit::recording::param::make_debug_string): New.

	(gcc::jit::recording::function::get_return_type): New accessor.
	(gcc::jit::recording::function::make_debug_string): New.

	(gcc::jit::recording::label::make_debug_string): New.

	(gcc::jit::recording::global): Eliminate field m_type in favor of
	that within the rvalue ultimate base class (via lvalue).
	(gcc::jit::recording::make_debug_string): New.

	(gcc::jit::recording::memento_of_new_rvalue_from_int): Eliminate
	field m_type in favor of that within the rvalue base class.
	(gcc::jit::recording::memento_of_new_rvalue_from_int::
	make_debug_string): New.

	(gcc::jit::recording::memento_of_new_rvalue_from_double): Eliminate
	field m_type in favor of that within the rvalue base class.
	(gcc::jit::recording::memento_of_new_rvalue_from_double::
	make_debug_string): New.

	(gcc::jit::recording::memento_of_new_rvalue_from_ptr): Eliminate
	field m_type in favor of that within the rvalue base class.
	(gcc::jit::recording::memento_of_new_rvalue_from_ptr::
	make_debug_string): New.

	(gcc::jit::recording::memento_of_new_string_literal::
	memento_of_new_string_literal): Initialize type.
	(gcc::jit::recording::memento_of_new_string_literal::
	make_debug_string): New.

	(gcc::jit::recording::unary_op): Eliminate field m_result_type in
	favor of m_type within the rvalue base class.
	(gcc::jit::recording::unary_op::make_debug_string): New.

	(gcc::jit::recording::binary_op): Eliminate field m_result_type in
	favor of m_type within the rvalue base class.
	(gcc::jit::recording::binary_op::make_debug_string): New.

	(gcc::jit::recording::comparison): Eliminate field m_result_type
	in favor of m_type within the rvalue base class.
	(gcc::jit::recording::comparison::make_debug_string): New.

	(gcc::jit::recording::make_debug_string): New.

	(gcc::jit::recording::array_lookup::array_lookup): Initialize type
	by dereferencing the type of the pointer.
	(gcc::jit::recording::array_lookup::make_debug_string): New.

	(gcc::jit::recording::access_field_of_lvalue::
	access_field_of_lvalue): Initialize type from that of the field.
	(gcc::jit::recording::access_field_of_lvalue::
	make_debug_string): New.

	(gcc::jit::recording::access_field_rvalue::
	access_field_of_rvalue): Initialize type from that of the field.
	(gcc::jit::recording::access_field_rvalue::make_debug_string):
	New.

	(gcc::jit::recording::dereference_field_rvalue::
	dereference_field_rvalue): Initialize type from that of the field.
	(gcc::jit::recording::dereference_field_rvalue::
	make_debug_string): New.

	(gcc::jit::recording::dereference_rvalue::dereference_rvalue):
	Initialize type by dereferencing the type of the pointer.
	(gcc::jit::recording::dereference_rvalue::make_debug_string): New.

	(gcc::jit::recording::get_address_of_lvalue::
	get_address_of_lvalue):  Initialize type by dereferencing the type
	of the pointer.
	(gcc::jit::recording::get_address_of_lvalue::make_debug_string):
	New.

	(gcc::jit::recording::local): Eliminate field m_type in favor of
	that within the rvalue ultimate base class (via lvalue).
	(gcc::jit::recording::make_debug_string): New.

	(gcc::jit::recording::eval::make_debug_string): New.
	(gcc::jit::recording::assignment::make_debug_string): New.
	(gcc::jit::recording::assignment_op::make_debug_string): New.
	(gcc::jit::recording::comment::make_debug_string): New.
	(gcc::jit::recording::conditional::make_debug_string): New.
	(gcc::jit::recording::place_label::make_debug_string): New.
	(gcc::jit::recording::jump::make_debug_string): New.
	(gcc::jit::recording::return_::make_debug_string): New.
	(gcc::jit::recording::loop::make_debug_string): New.
	(gcc::jit::recording::loop_end::make_debug_string): New.

	* internal-api.c (gcc::jit::recording::context::context):
	Initialize m_FILE_type and m_basic_types.
	(gcc::jit::recording::context::record): Move here from
	internal-api.h.
	(gcc::jit::recording::context::replay_into): Add a disabled way to
	log everything during a replay, exercising the stringification
	machinery.
	(gcc::jit::recording::context::get_type): Cache and reuse the
	types, so that repeated calls on the context give the same object.
	(gcc::jit::recording::context::get_opaque_FILE_type): New, for
	the result of dereferencing (FILE*), mostly so that fuzz-testing
	that tries this gets something sane back.
	(gcc::jit::recording::memento::get_debug_string): New method,
	giving a way to easily get a descriptive (const char *) for
	an API entity.  Internally, it lazily calls the make_debug_string
	virtual function, storing the result in m_debug_string.

	(gcc::jit::recording::string::string): Rename field m_copy to m_buffer.
	(gcc::jit::recording::string::~string): Likewise.
	(gcc::jit::recording::string::from_printf): New factory function,
	to make it easy to implement the make_debug_string hooks.

	(gcc::jit::recording::string::make_debug_string): New.

	(gcc::jit::recording::location::make_debug_string): New.

	(gcc::jit::recording::memento_of_get_type::dereference): New.

	(get_type_strings): New table of strings, for use by...
	(gcc::jit::recording::memento_of_get_type::make_debug_string): New.

	(gcc::jit::recording::memento_of_get_pointer::make_debug_string): New.

	(gcc::jit::recording::memento_of_get_const::make_debug_string): New.

	(gcc::jit::recording::field::make_debug_string): New.

	(gcc::jit::recording::struct_::struct_): Move here from
	internal-api.h.  Mark all fields as belonging to the new struct.

	(gcc::jit::recording::struct_::dereference): New.
	(gcc::jit::recording::struct_::make_debug_string): New.

	(gcc::jit::recording::function::make_debug_string): New.

	(gcc::jit::recording::label::make_debug_string): New.

	(gcc::jit::recording::memento_of_new_rvalue_from_int::
	make_debug_string): New.
	(gcc::jit::recording::memento_of_new_rvalue_from_double::
	make_debug_string): New.
	(gcc::jit::recording::memento_of_new_rvalue_from_ptr::
	make_debug_string): New.
	(gcc::jit::recording::memento_of_new_string_literal::
	make_debug_string): New.

	(gcc::jit::recording::unary_op::replay_into): Use get_type ()
	rather than the now-defunct m_result_type.
	(gcc::jit::recording::binary_op::replay_into): Likewise.

	(unary_op_strings): New table of strings for use by...
	(gcc::jit::recording::unary_op::make_debug_string): New.

	(binary_op_strings): New table of strings for use by...
	(gcc::jit::recording::binary_op::make_debug_string): New.

	(comparison_strings): New table of strings for use by...
	(gcc::jit::recording::comparison::make_debug_string): New.

	(gcc::jit::recording::call::call): Initialize the type.
	(gcc::jit::recording::call::make_debug_string): New.

	(gcc::jit::recording::array_lookup::make_debug_string): New.
	(gcc::jit::recording::access_field_of_lvalue::
	make_debug_string): New.
	(gcc::jit::recording::access_field_rvalue::
	make_debug_string): New.
	(gcc::jit::recording::dereference_field_rvalue::
	make_debug_string): New.
	(gcc::jit::recording::dereference_rvalue::make_debug_string): New.
	(gcc::jit::recording::get_address_of_lvalue::
	make_debug_string): New.
	(gcc::jit::recording::eval::make_debug_string): New.
	(gcc::jit::recording::assignment::make_debug_string): New.
	(gcc::jit::recording::assignment_op::make_debug_string): New.
	(gcc::jit::recording::comment::make_debug_string): New.
	(gcc::jit::recording::conditional::make_debug_string): New.
	(gcc::jit::recording::place_label::make_debug_string): New.
	(gcc::jit::recording::jump::make_debug_string): New.
	(gcc::jit::recording::return_::make_debug_string): New.
	(gcc::jit::recording::loop::make_debug_string): New.
	(gcc::jit::recording::loop_end::make_debug_string): New.

gcc/testsuite/
	* jit.dg/test-error-accessing-field-in-other-struct.c: New test
	case.
	* jit.dg/test-error-dereference-field-of-non-pointer.c: Likewise.
	* jit.dg/test-error-dereference-read-of-non-pointer.c: Likewise.
	* jit.dg/test-error-mismatching-types-in-assignment.c: Likewise.
	* jit.dg/test-error-return-within-void-function.c: Likewise.
Check argument types within gcc_jit_context_new_call

gcc/jit/
	* internal-api.c (gcc::jit::recording::type::get_pointer):
	Ensure that repeated calls yield the same type.
	(gcc::jit::recording::memento_of_get_pointer::
	accepts_writes_from): New.
	(gcc::jit::recording::context::new_call): Move
	the existing argument checking to...

	* libgccjit.c (gcc_jit_context_new_call): ...here, and add
	checking of the types of the arguments against the function.
	(RETURN_VAL_IF_FAIL_PRINTF6): New.
	(RETURN_NULL_IF_FAIL_PRINTF6): New.

	* internal-api.h (gcc::jit::recording::type): New field
	m_pointer_to_this_type, for use by get_pointer method.
	(gcc::jit::recording::memento_of_get_pointer::
	accepts_writes_from): New.
	(gcc::jit::recording::function::get_param): New.

	* TODO.rst (argument checking of gcc_jit_context_new_call): Done.

gcc/testsuite/
	* jit.dg/test-error-call-with-mismatching-args.c: New test case.
Check that code labels are placed exactly once

gcc/jit/
	* TODO.rst: Label-placement is now checked.

	* internal-api.c (gcc::jit::recording::context::replay_into): Give
	up if any errors occur during the playback.
	(gcc::jit::recording::label::replay_into): Issue an error if the
	label has not yet been placed (at playback time).
	(gcc::jit::recording::place_label::place_label): Move this here
	from internal-api.h.  Issue an error if the label has already
	been placed (at recording time).

	* internal-api.h (gcc::jit::recording::label): Add an
	m_has_been_placed field, and make class place_label a friend so
	it can set it.
	(gcc::jit::recording::label::has_been_placed): New accessor.
	(gcc::jit::recording::place_label::place_label): Move to
	internal-api.c.

	(gcc::jit::playback::context::errors_occurred): Make public, for
	use by gcc::jit::recording::context::replay_into.

gcc/testsuite/
	* jit.dg/test-error-label-already-placed.c: New test case.
	* jit.dg/test-error-unplaced-label.c: New test case.
Update the names of some parameters to be more descriptive

gcc/jit/
	* libgccjit.h (gcc_jit_context_new_rvalue_from_int): Give the type
	parameter a more descriptive name.
	(gcc_jit_context_zero): Likewise.
	(gcc_jit_context_one): Likewise.
	(gcc_jit_context_new_rvalue_from_double): Likewise.
	(gcc_jit_context_new_rvalue_from_ptr): Likewise.

	* libgccjit.c (gcc_jit_context_new_rvalue_from_int): Likewise.
	(gcc_jit_context_zero): Likewise.
	(gcc_jit_context_one): Likewise.
	(gcc_jit_context_new_rvalue_from_double): Likewise.
	(gcc_jit_context_new_rvalue_from_ptr): Likewise.

	* internal-api.h (gcc::jit::recording::context::
	new_rvalue_from_int): Likewise.
	(gcc::jit::recording::context::
	new_rvalue_from_double): Likewise.
	(gcc::jit::recording::memento_of_new_rvalue_from_int::
	memento_of_new_rvalue_from_int): Likewise.
	(gcc::jit::recording::memento_of_new_rvalue_from_double::
	memento_of_new_rvalue_from_double): Likewise.
	(gcc::jit::recording::memento_of_new_rvalue_from_ptr::
	memento_of_new_rvalue_from_ptr): Likewise.
Add libgccjit++.h, a C++ wrapper to the API

The libgccjit C API is relatively low-level and thus should be easy to
maintain a stable ABI for, and to wrap from many different languages.

However, it's rather verbose.

This commit adds an example of a C++ wrapper, which makes use of methods,
overloading, and inheritance, giving a much more terse API.

It's all done as small inline functions wrapped around the raw C pointers,
within one header, so it shouldn't need to be built as a separate library,
hence this shouldn't add an ABI (I hope), just an API.

As an example, I ported test-quadratic.c to it (as a new file:
test-quadratic.cc), and was able to considerably reduce the line-count
whilst fitting within a 80-column limit:

# line, word, byte counts:
$ wc \
    gcc/testsuite/jit.dg/test-quadratic.c \
    gcc/testsuite/jit.dg/test-quadratic.cc
  487  1066 12748 gcc/testsuite/jit.dg/test-quadratic.c
  369   911  9985 gcc/testsuite/jit.dg/test-quadratic.cc
  856  1977 22733 total

Caveat: I haven't yet managed to get DejaGnu to run this as part of
the test suite; I've been building/running it manually for now.

gcc/jit/
	* libgccjit++.h: New file - a C++ wrapper for the libgccjit.h API.

	* TODO.rst ("Test Suite"): New section, adding note about C++
	tests.

gcc/testsuite/
	* jit.dg/test-quadratic.cc: New file - a translation of
	test-quadratic.c to the libgccjit++.h C++ API.
Add a gcc_jit_object base class, exposing debug strings and contexts

Expose the debug string facility to client code, to make it easier to
write client code.  In doing so, it makes sense to simply expose the
ultimate base class of "contextual object" as gcc_jit_object, to better
express which objects are "contextual", and to support querying which
context an object is within.

Make similar changes to the C++ API, including the ability to use "<<"
with jit objects.

As well as being usable from client code, this allows for usage from
within the debugger, for the C API:

  (gdb) call gcc_jit_object_get_debug_string ((gcc_jit_object *)rvalue)
  $7 = 0x610220 "R1 < R2"

and for the C++ API:

  (gdb) call lvalue.get_debug_string ()
  $4 = "q->discriminant"
  (gdb) call rvalue.get_debug_string ()
  $5 = "q->b * q->b - (double)4 * q->a * q->c"

gcc/jit/
	* libgccjit.h (struct gcc_jit_object): New.
	(gcc_jit_object_get_context): New.
	(gcc_jit_object_get_debug_string): New.
	(gcc_jit_location_as_object): New.
	(gcc_jit_type_as_object): New.
	(gcc_jit_field_as_object): New.
	(gcc_jit_param_as_object): New.
	(gcc_jit_function_as_object): New.
	(gcc_jit_label_as_object): New.
	(gcc_jit_lvalue_as_object): New.
	(gcc_jit_rvalue_as_object): New.
	(gcc_jit_loop_as_object): New.

	* libgccjit.map (gcc_jit_field_as_object): New.
	(gcc_jit_function_as_object): New.
	(gcc_jit_label_as_object): New.
	(gcc_jit_location_as_object): New.
	(gcc_jit_loop_as_object): New.
	(gcc_jit_lvalue_as_object): New.
	(gcc_jit_object_get_context): New.
	(gcc_jit_object_get_debug_string): New.
	(gcc_jit_param_as_object): New.
	(gcc_jit_rvalue_as_object): New.
	(gcc_jit_type_as_object): New.

	* libgccjit.c (struct gcc_jit_object): New.
	(gcc_jit_location_as_object): New.
	(gcc_jit_type_as_object): New.
	(gcc_jit_field_as_object): New.
	(gcc_jit_param_as_object): New.
	(gcc_jit_function_as_object): New.
	(gcc_jit_label_as_object): New.
	(gcc_jit_lvalue_as_object): New.
	(gcc_jit_rvalue_as_object): New.
	(gcc_jit_object_get_context): New.
	(gcc_jit_object_get_debug_string): New.
	(gcc_jit_loop_as_object): New.
	* internal-api.h (gcc::jit::recording::memento::get_context): New.
	(gcc::jit::recording::memento::as_object): New.

	* libgccjit++.h: Require iostream, for std::ostream.
	(class object): New base class.
	(operator << (std::ostream& stream, const object &obj)): New.
	(location): Inherit from the new "object" base class.
	(location::m_inner_loc): Remove, in favor of...
	(location::get_inner_location): ...new method.
	(field): Inherit from the new "object" base class.
	(field::m_inner_field): Remove, in favor of...
	(field::get_inner_field): ...new method.
	(type): Inherit from the new "object" base class.
	(type::m_inner_type): Remove, in favor of...
	(type::get_inner_type): ...new method.
	(function): Inherit from the new "object" base class.
	(function::m_inner_func): Remove, in favor of...
	(function::get_inner_function): ...new method.
	(label): Inherit from the new "object" base class.
	(label::m_inner_label): Remove, in favor of...
	(label::get_inner_label): ...new method.
	(rvalue) Inherit from the new "object" base class.
	(rvalue::m_inner_rvalue): Remove, in favor of...
	(rvalue::get_inner_rvalue): ...new method.

	(context::new_field): Update for move of inner pointer to the
	"object" base class.
	(context::new_struct_type): Likewise.
	(context::new_param): Likewise.
	(context::new_function): Likewise.
	(context::new_rvalue): Likewise.
	(context::zero): Likewise.
	(context::one): Likewise.
	(context::new_rvalue): Likewise.
	(context::new_rvalue): Likewise.
	(context::new_unary_op): Likewise.
	(context::new_binary_op): Likewise.
	(context::new_comparison): Likewise.
	(context::new_call): Likewise.

	(object::get_debug_string): New.
	(object::object): New.
	(object::get_inner_object): New.
	(operator << (std::ostream&, const object &)): New.

	(location::location): Update for move of inner pointer to the
	"object" base class.
	(location::get_inner_location): New.

	(field::field): Update for move of inner pointer to the
	"object" base class.
	(field::get_inner_field): New.

	(type::type): Update for move of inner pointer to the
	"object" base class.
	(type::get_pointer): Likewise.
	(type::get_inner_type): New.

	(function::function): Update for move of inner pointer to the
	"object" base class.
	(function::new_forward_label): Likewise.
	(function::new_local): Likewise.
	(function::add_eval): Likewise.
	(function::add_assignment): Likewise.
	(function::add_assignment_op): Likewise.
	(function::add_comment): Likewise.
	(function::add_conditional): Likewise.
	(function::add_label): Likewise.
	(function::place_forward_label): Likewise.
	(function::add_jump): Likewise.
	(function::add_return): Likewise.
	(function::get_inner_function): New.

	(label::label): Update for move of inner pointer to the "object"
	base class.
	(label::get_inner_label): New

	(rvalue::rvalue): Update for move of inner pointer to the "object"
	base class.
	(rvalue::get_inner_rvalue): New.
	(rvalue::access_field): Likewise.
	(rvalue::dereference_field): Likewise.
	(rvalue::dereference): Likewise.

	(lvalue::get_inner_lvalue): Update for move of inner pointer to
	the "object" base class.
	(lvalue::access_field): Likewise.
	(lvalue::get_address): Likewise.

gcc/testsuite/
	* jit.dg/harness.h (check_string_value): Add a forward declaration,
	so that we can use CHECK_STRING_VALUE from within tests used by
	test-combination.c.

	* jit.dg/test-expressions.c (make_test_of_unary_op): Return a debug
	stringification of the operation so that it be sanity-checked.
	(make_test_of_binary_op): Likewise.
	(make_test_of_comparison): Likewise.
	(make_tests_of_unary_ops): Verify that said stringifications are
	indeed sane.
	(make_tests_of_binary_ops): Likewise.
	(make_tests_of_comparisons): Likewise.

	* jit.dg/test-quadratic.cc (make_types): Verify that the
	get_debug_string method works.
	(make_test_quadratic): Likewise, also, verify that the <<
	operator works.
Improvements to array access (API change and additions)

The following commit adds a way to create an array type from an existing
type:

  /* Given type "T", get type "T[N]" (for a constant N).  */
  extern gcc_jit_type *
  gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
				  gcc_jit_location *loc,
				  gcc_jit_type *element_type,
				  int num_elements);

and renames the array access API from:
	gcc_jit_context_new_array_lookup
to:
	gcc_jit_context_new_array_access
changing it to return an lvalue rather than an rvalue.

It also adds a helper function:

  extern gcc_jit_loop *
  gcc_jit_function_new_loop_over_range (gcc_jit_function *func,
					gcc_jit_location *loc,
					gcc_jit_lvalue *iteration_var,
					gcc_jit_rvalue *start_of_range,
					gcc_jit_rvalue *upper_bound_of_range,
					gcc_jit_rvalue *step);

for creating loops of this form more easily:
	for (i = start_of_range; i < upper_bound_of_range; i += step)
	{
	   BODY;
	}

 "start_of_range" can be NULL, in which case 0 is used.
 "upper_bound_of_range" must be non-NULL.
 "step" can be NULL, in which case 1 is used.

gcc/jit/
	* libgccjit.h (gcc_jit_context_new_array_type): New.
	(gcc_jit_context_new_array_lookup): Rename to...
	(gcc_jit_context_new_array_access): ...this, and change return
	type from rvalue to lvalue.
	(gcc_jit_function_new_loop_over_range): New.

	* libgccjit.map (gcc_jit_context_new_array_lookup): Rename to...
	(gcc_jit_context_new_array_access): ..this.
	(gcc_jit_context_new_array_type): New.
	(gcc_jit_function_new_loop_over_range): New.

	* libgccjit++.h (gccjit::context::new_array_type): New methods.
	(gccjit::context::new_array_access): New methods.

	* libgccjit.c (gcc_jit_context_new_array_type): New.
	(gcc_jit_context_new_array_lookup): Rename to...
	(gcc_jit_context_new_array_access): ...this, and change return
	type from rvalue to lvalue.
	(gcc_jit_function_new_loop): Provide NULL for the added arguments
	for the underlying API.
	(gcc_jit_function_new_loop_over_range): New.

	* internal-api.h (gcc::jit::recording::context::
	new_array_type): New.
	(gcc::jit::recording::context::new_array_lookup): Rename to...
	(gcc::jit::recording::context::new_array_access): ...this, and
	change return type from an rvalue to an lvalue.
	(gcc::jit::recording::array_type): New subclass of type.
	(gcc::jit::recording::function::new_loop): Add iteration_var and
	step params, so that we can add a += when the loop ends.
	(gcc::jit::recording::array_lookup): Rename to...
	(gcc::jit::recording::array_access): ...this, and subclass from
	lvalue rathern than rvalue.
	(gcc::jit::recording::loop): Add optional iteration_var and
	step fields, for use by gcc_jit_function_new_loop_over_range so
	that, if present, we can add a += when the loop ends.

	(gcc::jit::playback::context::new_array_type): New.
	(gcc::jit::playback::context::new_array_lookup): Rename to...
	(gcc::jit::playback::context::new_array_access): ...this, and
	change return type from an rvalue to an lvalue.

	* internal-api.c (gcc::jit::recording::context::new_array_type): New.
	(gcc::jit::recording::context::new_array_lookup): Rename to...
	(gcc::jit::recording::context::new_array_access): ...this, and
	change return type from an rvalue to an lvalue.
	(gcc::jit::recording::array_type::dereference): New.
	(gcc::jit::recording::array_type::replay_into): New.
	(gcc::jit::recording::array_type::make_debug_string): New.
	(gcc::jit::recording::function::new_loop): Add iteration_var and
	step params.
	(gcc::jit::recording::array_lookup): Rename to...
	(gcc::jit::recording::array_access): ...this.
	(gcc::jit::recording::loop::end): If we have an iteration_var, and
	thus a step, inject a += operation immediately before the loop
	end.
	(gcc::jit::playback::context::new_array_type): New.
	(gcc::jit::playback::context::new_array_lookup): Rename to...
	(gcc::jit::playback::context::new_array_access): ...this, and
	change return type from an rvalue to an lvalue.

gcc/testsuite/
	* jit.dg/test-arrays.c: New test case, verifying that array types
	work as expected (and using the the new
	gcc_jit_function_new_loop_over_range API call).

	* jit.dg/test-dot-product.c (create_code): Update for API changes to
	array access.