Committed to branch dmalcolm/jit: Error-handling in the C API works by returning NULL when an error occurs (and setting an error on the context), and handling NULL inputs by immediately returning NULL (setting another error). Hence the presence of a NULL indicates some kind of error has occurred.
Update the C++ API to check for NULL pointers in the constructors for the various wrappers classes, throwing an exception if one if passed in. Hence any erroneous use of the API (e.g. type-mismatches) will lead to immediate failure, rather than the previous behavior of a flurry of text on stderr. Also, make gccjit::context::m_inner private. gcc/jit/ * libgccjit++.h (gccjit::error): New class, for exceptions. (gccjit::context::get_inner_context): New accessor, so that we can... (gccjit::context::m_inner_ctxt): Make private. (gccjit::context::context): Throw a gccjit::error if a NULL context is passed in. (gccjit::context::compile): Throw a gccjit::error if a NULL result is returned from the C API, which indicates an error. (gccjit::object::object): Throw a gccjit::error if a NULL object is passed in, since that indicates that an error has occurred. (gccjit::location::location): In the default ctor, call the base class default ctor rather than passing in a NULL to the single-argument ctor, since the latter now indicates an error has occurred at the C API level. (gccjit::field::field): Likewise. (gccjit::type::type): Likewise. (gccjit::function::function): Likewise. (gccjit::block::block): Likewise. (gccjit::rvalue::rvalue): Likewise. --- gcc/jit/ChangeLog.jit | 23 +++++++++++++++++++++++ gcc/jit/libgccjit++.h | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 223fd6a..fcb0244 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,3 +1,26 @@ +2014-03-10 David Malcolm <dmalc...@redhat.com> + + * libgccjit++.h (gccjit::error): New class, for exceptions. + (gccjit::context::get_inner_context): New accessor, so that we + can... + (gccjit::context::m_inner_ctxt): Make private. + (gccjit::context::context): Throw a gccjit::error if a NULL + context is passed in. + (gccjit::context::compile): Throw a gccjit::error if a NULL + result is returned from the C API, which indicates an error. + (gccjit::object::object): Throw a gccjit::error if a NULL + object is passed in, since that indicates that an error has + occurred. + (gccjit::location::location): In the default ctor, call the + base class default ctor rather than passing in a NULL to the + single-argument ctor, since the latter now indicates an error + has occurred at the C API level. + (gccjit::field::field): Likewise. + (gccjit::type::type): Likewise. + (gccjit::function::function): Likewise. + (gccjit::block::block): Likewise. + (gccjit::rvalue::rvalue): Likewise. + 2014-03-07 David Malcolm <dmalc...@redhat.com> * libgccjit.h (enum gcc_jit_function_kind): Add diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index 71bb855..cd02dde 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -26,6 +26,11 @@ namespace gccjit class rvalue; class lvalue; + /* Errors within the API become C++ exceptions of this class. */ + class error + { + }; + class object { public: @@ -68,6 +73,8 @@ namespace gccjit gccjit::context new_child_context (); + gcc_jit_context *get_inner_context () { return m_inner_ctxt; } + void release (); gcc_jit_result *compile (); @@ -251,7 +258,7 @@ namespace gccjit rvalue index, location loc = location ()); - public: + private: gcc_jit_context *m_inner_ctxt; }; @@ -473,7 +480,11 @@ inline context context::acquire () return context (gcc_jit_context_acquire ()); } inline context::context () : m_inner_ctxt (NULL) {} -inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner) {} +inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner) +{ + if (!inner) + throw error (); +} inline gccjit::context context::new_child_context () @@ -491,7 +502,10 @@ context::release () inline gcc_jit_result * context::compile () { - return gcc_jit_context_compile (m_inner_ctxt); + gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt); + if (!result) + throw error (); + return result; } inline void @@ -1026,7 +1040,11 @@ object::get_debug_string () const } inline object::object () : m_inner_obj (NULL) {} -inline object::object (gcc_jit_object *obj) : m_inner_obj (obj) {} +inline object::object (gcc_jit_object *obj) : m_inner_obj (obj) +{ + if (!obj) + throw error (); +} inline gcc_jit_object * object::get_inner_object () const @@ -1041,7 +1059,7 @@ operator << (std::ostream& stream, const object &obj) } // class location -inline location::location () : object (NULL) {} +inline location::location () : object () {} inline location::location (gcc_jit_location *loc) : object (gcc_jit_location_as_object (loc)) {} @@ -1054,7 +1072,7 @@ location::get_inner_location () const } // class field -inline field::field () : object (NULL) {} +inline field::field () : object () {} inline field::field (gcc_jit_field *inner) : object (gcc_jit_field_as_object (inner)) {} @@ -1067,7 +1085,7 @@ field::get_inner_field () const } // class type -inline type::type () : object (NULL) {} +inline type::type () : object () {} inline type::type (gcc_jit_type *inner) : object (gcc_jit_type_as_object (inner)) {} @@ -1118,7 +1136,7 @@ struct_::get_inner_struct () const } // class function -inline function::function () : object (NULL) {} +inline function::function () : object () {} inline function::function (gcc_jit_function *inner) : object (gcc_jit_function_as_object (inner)) {} @@ -1332,7 +1350,7 @@ function::operator() (rvalue arg0, rvalue arg1, rvalue arg2, } // class block -inline block::block () : object (NULL) {} +inline block::block () : object () {} inline block::block (gcc_jit_block *inner) : object (gcc_jit_block_as_object (inner)) {} @@ -1345,7 +1363,7 @@ block::get_inner_block () const } // class rvalue -inline rvalue::rvalue () : object (NULL) {} +inline rvalue::rvalue () : object () {} inline rvalue::rvalue (gcc_jit_rvalue *inner) : object (gcc_jit_rvalue_as_object (inner)) {} -- 1.7.11.7