jit: New API entrypoint: gcc_jit_context_get_last_error

gcc/jit/ChangeLog:
	* docs/topics/contexts.rst (Error-handling): Document new
	entrypoint gcc_jit_context_get_last_error.
	* docs/_build/texinfo/libgccjit.texi: Regenerate.
	* jit-recording.c (gcc::jit::recording::context::context):
	Initialize new fields "m_last_error_str" and
	"m_owns_last_error_str".
	(gcc::jit::recording::context::~context): Clean up
	m_last_error_str, if needed.
	(gcc::jit::recording::context::add_error_va): Update
	m_last_error_str and m_owns_last_error_str, freeing the old
	value if appropriate.
	(gcc::jit::recording::context::get_last_error): New function.
	* jit-recording.h (gcc::jit::recording::context::get_last_error):
	New function.
	(gcc::jit::recording::context): New fields m_last_error_str and
	m_owns_last_error_str.
	* libgccjit.c (gcc_jit_context_get_last_error): New function.
	* libgccjit.h (gcc_jit_context_get_last_error): New declaration.
	* libgccjit.map (gcc_jit_context_get_last_error): New function.

gcc/testsuite/ChangeLog:
	* jit.dg/test-error-block-in-wrong-function.c (verify_code):
	Verify the result of gcc_jit_context_get_last_error.
	* jit.dg/test-error-null-passed-to-api.c (verify_code): Likewise.

From-SVN: r219363
This commit is contained in:
David Malcolm 2015-01-08 21:52:35 +00:00 committed by David Malcolm
parent 204a913bda
commit 303e1d56c6
11 changed files with 505 additions and 386 deletions

View File

@ -1,3 +1,25 @@
2015-01-08 David Malcolm <dmalcolm@redhat.com>
* docs/topics/contexts.rst (Error-handling): Document new
entrypoint gcc_jit_context_get_last_error.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-recording.c (gcc::jit::recording::context::context):
Initialize new fields "m_last_error_str" and
"m_owns_last_error_str".
(gcc::jit::recording::context::~context): Clean up
m_last_error_str, if needed.
(gcc::jit::recording::context::add_error_va): Update
m_last_error_str and m_owns_last_error_str, freeing the old
value if appropriate.
(gcc::jit::recording::context::get_last_error): New function.
* jit-recording.h (gcc::jit::recording::context::get_last_error):
New function.
(gcc::jit::recording::context): New fields m_last_error_str and
m_owns_last_error_str.
* libgccjit.c (gcc_jit_context_get_last_error): New function.
* libgccjit.h (gcc_jit_context_get_last_error): New declaration.
* libgccjit.map (gcc_jit_context_get_last_error): New function.
2015-01-08 David Malcolm <dmalcolm@redhat.com>
* Make-lang.in (jit_OBJS): Add jit/jit-logging.o.

File diff suppressed because it is too large Load Diff

View File

@ -123,7 +123,9 @@ In general, if an error occurs when using an API entrypoint, the
entrypoint returns NULL. You don't have to check everywhere for NULL
results, since the API handles a NULL being passed in for any
argument by issuing another error. This typically leads to a cascade of
followup error messages, but is safe (albeit verbose).
followup error messages, but is safe (albeit verbose). The first error
message is usually the one to pay attention to, since it is likely to
be responsible for all of the rest:
.. function:: const char *\
gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
@ -135,6 +137,20 @@ followup error messages, but is safe (albeit verbose).
If no errors occurred, this will be NULL.
If you are wrapping the C API for a higher-level language that supports
exception-handling, you may instead by interested in the last error that
occurred on the context, so that you can embed this in an exception:
.. function:: const char *\
gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
Returns the last error message that occurred on the context.
The returned string is valid for the rest of the lifetime of the
context.
If no errors occurred, this will be NULL.
Debugging
---------

View File

@ -175,6 +175,8 @@ recording::context::context (context *parent_ctxt)
m_error_count (0),
m_first_error_str (NULL),
m_owns_first_error_str (false),
m_last_error_str (NULL),
m_owns_last_error_str (false),
m_mementos (),
m_compound_types (),
m_functions (),
@ -230,6 +232,10 @@ recording::context::~context ()
if (m_owns_first_error_str)
free (m_first_error_str);
if (m_owns_last_error_str)
if (m_last_error_str != m_first_error_str)
free (m_last_error_str);
}
/* Add the given mememto to the list of those tracked by this
@ -984,9 +990,12 @@ recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
m_first_error_str = const_cast <char *> (errmsg);
m_owns_first_error_str = has_ownership;
}
else
if (has_ownership)
free (malloced_msg);
if (m_owns_last_error_str)
if (m_last_error_str != m_first_error_str)
free (m_last_error_str);
m_last_error_str = const_cast <char *> (errmsg);
m_owns_last_error_str = has_ownership;
m_error_count++;
}
@ -1003,6 +1012,18 @@ recording::context::get_first_error () const
return m_first_error_str;
}
/* Get the message for the last error that occurred on this context, or
NULL if no errors have occurred on it.
Implements the post-error-checking part of
gcc_jit_context_get_last_error. */
const char *
recording::context::get_last_error () const
{
return m_last_error_str;
}
/* Lazily generate and record a recording::type representing an opaque
struct named "FILE".

View File

@ -235,6 +235,9 @@ public:
const char *
get_first_error () const;
const char *
get_last_error () const;
bool errors_occurred () const
{
if (m_parent_ctxt)
@ -261,6 +264,9 @@ private:
char *m_first_error_str;
bool m_owns_first_error_str;
char *m_last_error_str;
bool m_owns_last_error_str;
char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];

View File

@ -2161,6 +2161,20 @@ gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
return ctxt->get_first_error ();
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
gcc::jit::recording::context::get_last_error method in
jit-recording.c. */
const char *
gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
return ctxt->get_last_error ();
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the

View File

@ -279,6 +279,16 @@ gcc_jit_context_set_logfile (gcc_jit_context *ctxt,
extern const char *
gcc_jit_context_get_first_error (gcc_jit_context *ctxt);
/* To be called after a compile, this gives the last error message
that occurred on the context.
The returned string is valid for the rest of the lifetime of the
context.
If no errors occurred, this will be NULL. */
extern const char *
gcc_jit_context_get_last_error (gcc_jit_context *ctxt);
/* Locate a given function within the built machine code.
This will need to be cast to a function pointer of the
correct type before it can be called. */

View File

@ -36,6 +36,7 @@
gcc_jit_context_enable_dump;
gcc_jit_context_get_builtin_function;
gcc_jit_context_get_first_error;
gcc_jit_context_get_last_error;
gcc_jit_context_get_type;
gcc_jit_context_get_int_type;
gcc_jit_context_new_array_access;

View File

@ -1,3 +1,9 @@
2015-01-08 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-error-block-in-wrong-function.c (verify_code):
Verify the result of gcc_jit_context_get_last_error.
* jit.dg/test-error-null-passed-to-api.c (verify_code): Likewise.
2015-01-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/63989

View File

@ -62,4 +62,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
" source block initial is in function test_fn"
" whereas target block block_within_other_fn"
" is in function other_fn");
/* Example of a testcase in which the last error != first error. */
CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
"unterminated block in other_fn: block_within_other_fn");
}

View File

@ -27,5 +27,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
/* Verify that the correct error message was emitted. */
CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
"gcc_jit_context_new_function: NULL return_type");
CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
"gcc_jit_context_new_function: NULL return_type");
}