/**
    The exception module defines all system-level exceptions and provides a
    mechanism to alter system-level error handling.

    Copyright: Copyright Sean Kelly 2005 - 2013.
    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
    Authors:   Sean Kelly and $(HTTP jmdavisprog.com, Jonathan M Davis)
    Source:    $(DRUNTIMESRC core/_exception.d)
 */
module core.exception;

// Compiler lowers final switch default case to this (which is a runtime error)
void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
{
    // Consider making this a compile time check.
    version (D_Exceptions)
        throw staticError!SwitchError("No appropriate switch clause found", file, line, null);
    else
        assert(0, "No appropriate switch clause found");
}

/*
 * Make sure template __switch_errorT is always instantiated when building
 * druntime. This works around https://issues.dlang.org/show_bug.cgi?id=20802.
 * When druntime and phobos are compiled with -release, the instance for
 * __switch_errorT is not needed. An application compiled with -release
 * could need the instance for __switch_errorT, but the compiler would
 * not generate code for it, because it assumes, that it was already
 * generated for druntime. Always including the instance in a compiled
 * druntime allows to use an application without -release with druntime
 * with -release.
 */
private alias dummy__switch_errorT = __switch_errorT!();

/**
 * Thrown on a range error.
 */
class RangeError : Error
{
    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( "Range violation", file, line, next );
    }

    protected this( string msg, string file, size_t line, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( msg, file, line, next );
    }
}

unittest
{
    {
        auto re = new RangeError();
        assert(re.file == __FILE__);
        assert(re.line == __LINE__ - 2);
        assert(re.next is null);
        assert(re.msg == "Range violation");
    }

    {
        auto re = new RangeError("hello", 42, new Exception("It's an Exception!"));
        assert(re.file == "hello");
        assert(re.line == 42);
        assert(re.next !is null);
        assert(re.msg == "Range violation");
    }
}

/**
 * Thrown when an out of bounds array index is accessed.
 */
class ArrayIndexError : RangeError
{
    /// Index into array
    const size_t index;
    /// Length of indexed array
    const size_t length;

    // Buffer to avoid GC allocations
    private immutable char[100] msgBuf = '\0';

    this(size_t index, size_t length, string file = __FILE__,
         size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe
    {
        this.index  = index;
        this.length = length;

        // Constructing the message is a bit clumsy:
        // It's essentially `printf("index [%zu] is out of bounds for array of length [%zu]", index, length)`,
        // but even `snprintf` isn't `pure`.
        // Also string concatenation isn't `@nogc`, and casting to/from immutable isn't `@safe`
        import core.internal.string : unsignedToTempString;
        char[msgBuf.length] buf = void;
        char[20] tmpBuf = void;
        char[] sink = buf[];
        sink.rangeMsgPut("index [");
        sink.rangeMsgPut(unsignedToTempString!10(index, tmpBuf));
        sink.rangeMsgPut("] is out of bounds for array of length ");
        sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf));
        this.msgBuf = buf;
        super(msgBuf[0..$-sink.length], file, line, next);
    }
}

@safe pure unittest
{
    assert(new ArrayIndexError(900, 700).msg == "index [900] is out of bounds for array of length 700");
    // Ensure msg buffer doesn't overflow on large numbers
    assert(new ArrayIndexError(size_t.max, size_t.max-1).msg);
}

unittest
{
    try
    {
        _d_arraybounds_indexp("test", 400, 9, 3);
        assert(0, "no ArrayIndexError thrown");
    }
    catch (ArrayIndexError re)
    {
        assert(re.file   == "test");
        assert(re.line   == 400);
        assert(re.index  == 9);
        assert(re.length == 3);
    }
}

/**
 * Thrown when an out of bounds array slice is created
 */
class ArraySliceError : RangeError
{
    /// Lower/upper bound passed to slice: `array[lower .. upper]`
    const size_t lower, upper;
    /// Length of sliced array
    const size_t length;

    private immutable char[120] msgBuf = '\0';

    this(size_t lower, size_t upper, size_t length, string file = __FILE__,
         size_t line = __LINE__, Throwable next = null) @nogc nothrow pure @safe
    {
        this.lower  = lower;
        this.upper  = upper;
        this.length = length;

        // Constructing the message is a bit clumsy for the same reasons as ArrayIndexError
        import core.internal.string : unsignedToTempString;
        char[msgBuf.length] buf = void;
        char[20] tmpBuf = void;
        char[] sink = buf;
        sink.rangeMsgPut("slice [");
        sink.rangeMsgPut(unsignedToTempString!10(lower, tmpBuf));
        sink.rangeMsgPut(" .. ");
        sink.rangeMsgPut(unsignedToTempString!10(upper, tmpBuf));
        sink.rangeMsgPut("] ");
        if (lower > upper)
        {
            sink.rangeMsgPut("has a larger lower index than upper index");
        }
        else
        {
            sink.rangeMsgPut("extends past source array of length ");
            sink.rangeMsgPut(unsignedToTempString!10(length, tmpBuf));
        }

        this.msgBuf = buf;
        super(msgBuf[0..$-sink.length], file, line, next);
    }
}

@safe pure unittest
{
    assert(new ArraySliceError(40, 80, 20).msg == "slice [40 .. 80] extends past source array of length 20");
    assert(new ArraySliceError(90, 70, 20).msg == "slice [90 .. 70] has a larger lower index than upper index");
    // Ensure msg buffer doesn't overflow on large numbers
    assert(new ArraySliceError(size_t.max, size_t.max, size_t.max-1).msg);
}

unittest
{
    try
    {
        _d_arraybounds_slicep("test", 400, 1, 7, 3);
        assert(0, "no ArraySliceError thrown");
    }
    catch (ArraySliceError re)
    {
        assert(re.file   == "test");
        assert(re.line   == 400);
        assert(re.lower  == 1);
        assert(re.upper  == 7);
        assert(re.length == 3);
    }
}

/// Mini `std.range.primitives: put` for constructor of ArraySliceError / ArrayIndexError
private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure @safe
{
    assert(r.length >= e.length); // don't throw ArraySliceError inside ArrayIndexError ctor
    r[0 .. e.length] = e[];
    r = r[e.length .. $];
}

/**
 * Thrown on an assert error.
 */
class AssertError : Error
{
    @safe pure nothrow @nogc this( string file, size_t line )
    {
        this(cast(Throwable)null, file, line);
    }

    @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
    {
        this( "Assertion failure", file, line, next);
    }

    @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
    {
        super( msg, file, line, next );
    }
}

unittest
{
    {
        auto ae = new AssertError("hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError(new Exception("It's an Exception!"));
        assert(ae.file == __FILE__);
        assert(ae.line == __LINE__ - 2);
        assert(ae.next !is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError(new Exception("It's an Exception!"), "hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next !is null);
        assert(ae.msg == "Assertion failure");
    }

    {
        auto ae = new AssertError("msg");
        assert(ae.file == __FILE__);
        assert(ae.line == __LINE__ - 2);
        assert(ae.next is null);
        assert(ae.msg == "msg");
    }

    {
        auto ae = new AssertError("msg", "hello", 42);
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next is null);
        assert(ae.msg == "msg");
    }

    {
        auto ae = new AssertError("msg", "hello", 42, new Exception("It's an Exception!"));
        assert(ae.file == "hello");
        assert(ae.line == 42);
        assert(ae.next !is null);
        assert(ae.msg == "msg");
    }
}

/**
 * When an unmapped pointer is accessed this may be thrown via a signal handler.
 */
class InvalidPointerError : Error
{
    @safe pure nothrow @nogc this(string file, size_t line)
    {
        this(file, line, cast(Throwable)null);
    }

    @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null)
    {
        this("Invalid pointer access", file, line, next);
    }

    @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
    {
        super(msg, file, line, next);
    }
}

/**
 * Thrown when a null dereference may occur.
 *
 * Depends upon null dereference check, or a signal handler to throw.
 */
class NullPointerError : InvalidPointerError
{
    @safe pure nothrow @nogc this(string file, size_t line)
    {
        this(file, line, cast(Throwable)null);
    }

    @safe pure nothrow @nogc this(string file = __FILE__, size_t line = __LINE__, Throwable next = null)
    {
        this("Null pointer dereference", file, line, next);
    }

    @safe pure nothrow @nogc this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
    {
        super(msg, file, line, next);
    }
}

/**
 * Thrown on finalize error.
 */
class FinalizeError : Error
{
    TypeInfo   info;

    this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow @nogc
    {
        this(ci, file, line, next);
    }

    this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( "Finalization error", file, line, next );
        info = ci;
    }

    override string toString() const @safe
    {
        return "An exception was thrown while finalizing an instance of " ~ info.toString();
    }
}

unittest
{
    ClassInfo info = new ClassInfo;
    info.name = "testInfo";

    {
        auto fe = new FinalizeError(info);
        assert(fe.file == __FILE__);
        assert(fe.line == __LINE__ - 2);
        assert(fe.next is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, new Exception("It's an Exception!"));
        assert(fe.file == __FILE__);
        assert(fe.line == __LINE__ - 2);
        assert(fe.next !is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, "hello", 42);
        assert(fe.file == "hello");
        assert(fe.line == 42);
        assert(fe.next is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }

    {
        auto fe = new FinalizeError(info, "hello", 42, new Exception("It's an Exception!"));
        assert(fe.file == "hello");
        assert(fe.line == 42);
        assert(fe.next !is null);
        assert(fe.msg == "Finalization error");
        assert(fe.info == info);
    }
}

/**
 * Thrown on an out of memory error.
 */
class OutOfMemoryError : Error
{
    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        this(true, file, line, next);
    }

    this(bool trace, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super("Memory allocation failed", file, line, next);
        if (!trace)
            this.info = SuppressTraceInfo.instance;
    }

    override string toString() const @trusted
    {
        return msg.length ? (cast()this).superToString() : "Memory allocation failed";
    }

    // kludge to call non-const super.toString
    private string superToString() @trusted
    {
        return super.toString();
    }
}

unittest
{
    {
        auto oome = new OutOfMemoryError();
        assert(oome.file == __FILE__);
        assert(oome.line == __LINE__ - 2);
        assert(oome.next is null);
        assert(oome.msg == "Memory allocation failed");
        assert(oome.toString.length);
    }

    {
        auto oome = new OutOfMemoryError("hello", 42, new Exception("It's an Exception!"));
        assert(oome.file == "hello");
        assert(oome.line == 42);
        assert(oome.next !is null);
        assert(oome.msg == "Memory allocation failed");
    }
}


/**
 * Thrown on an invalid memory operation.
 *
 * An invalid memory operation error occurs in circumstances when the garbage
 * collector has detected an operation it cannot reliably handle. The default
 * D GC is not re-entrant, so this can happen due to allocations done from
 * within finalizers called during a garbage collection cycle.
 */
class InvalidMemoryOperationError : Error
{
    this(string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( "Invalid memory operation", file, line, next );
    }

    override string toString() const @trusted
    {
        return msg.length ? (cast()this).superToString() : "Invalid memory operation";
    }

    // kludge to call non-const super.toString
    private string superToString() @trusted
    {
        return super.toString();
    }
}

unittest
{
    {
        auto oome = new InvalidMemoryOperationError();
        assert(oome.file == __FILE__);
        assert(oome.line == __LINE__ - 2);
        assert(oome.next is null);
        assert(oome.msg == "Invalid memory operation");
        assert(oome.toString.length);
    }

    {
        auto oome = new InvalidMemoryOperationError("hello", 42, new Exception("It's an Exception!"));
        assert(oome.file == "hello");
        assert(oome.line == 42);
        assert(oome.next !is null);
        assert(oome.msg == "Invalid memory operation");
    }
}


/**
* Thrown on a configuration error.
*/
class ForkError : Error
{
    this( string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @nogc nothrow pure @safe
    {
        super( "fork() failed", file, line, next );
    }
}


/**
 * Thrown on a switch error.
 */
class SwitchError : Error
{
    @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
    {
        super( msg, file, line, next );
    }
}

unittest
{
    {
        auto se = new SwitchError("No appropriate switch clause found");
        assert(se.file == __FILE__);
        assert(se.line == __LINE__ - 2);
        assert(se.next is null);
        assert(se.msg == "No appropriate switch clause found");
    }

    {
        auto se = new SwitchError("No appropriate switch clause found", "hello", 42, new Exception("It's an Exception!"));
        assert(se.file == "hello");
        assert(se.line == 42);
        assert(se.next !is null);
        assert(se.msg == "No appropriate switch clause found");
    }
}


/**
 * Thrown on a unicode conversion error.
 */
class UnicodeException : Exception
{
    size_t idx;

    this( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) @safe pure nothrow @nogc
    {
        super( msg, file, line, next );
        this.idx = idx;
    }
}

unittest
{
    {
        auto ue = new UnicodeException("msg", 2);
        assert(ue.file == __FILE__);
        assert(ue.line == __LINE__ - 2);
        assert(ue.next is null);
        assert(ue.msg == "msg");
        assert(ue.idx == 2);
    }

    {
        auto ue = new UnicodeException("msg", 2, "hello", 42, new Exception("It's an Exception!"));
        assert(ue.file == "hello");
        assert(ue.line == 42);
        assert(ue.next !is null);
        assert(ue.msg == "msg");
        assert(ue.idx == 2);
    }
}


///////////////////////////////////////////////////////////////////////////////
// Overrides
///////////////////////////////////////////////////////////////////////////////


// NOTE: One assert handler is used for all threads.  Thread-local
//       behavior should occur within the handler itself.  This delegate
//       is __gshared for now based on the assumption that it will only
//       set by the main thread during program initialization.
private __gshared
{
    AssertHandler _assertHandler = null;
    FilterThreadThrowableHandler _filterThreadThrowableHandler = null;
    NullDerefHandler _nullDerefHandler = null;
}


/**
Gets/sets assert hander. null means the default handler is used.
*/
alias AssertHandler = void function(string file, size_t line, string msg) nothrow;

/// ditto
@property AssertHandler assertHandler() @trusted nothrow @nogc
{
    return _assertHandler;
}

/// ditto
@property void assertHandler(AssertHandler handler) @trusted nothrow @nogc
{
    _assertHandler = handler;
}

/**
Gets/sets the Throwable filter function for threads. null means no handler is called.
*/
alias FilterThreadThrowableHandler = void function(ref Throwable) @system nothrow;

/// ditto
@property FilterThreadThrowableHandler filterThreadThrowableHandler() @trusted nothrow @nogc
{
    return _filterThreadThrowableHandler;
}

/// ditto
@property void filterThreadThrowableHandler(FilterThreadThrowableHandler handler) @trusted nothrow @nogc
{
    _filterThreadThrowableHandler = handler;
}

/**
Gets/sets null dereference handler. null means the default handler is used.
*/
alias NullDerefHandler = void function(string file, size_t line) nothrow;

/// ditto
@property NullDerefHandler nullDerefHandler() @trusted nothrow @nogc
{
    return _nullDerefHandler;
}

/// ditto
@property void nullDerefHandler(NullDerefHandler handler) @trusted nothrow @nogc
{
    _nullDerefHandler = handler;
}

///////////////////////////////////////////////////////////////////////////////
// Overridable Callbacks
///////////////////////////////////////////////////////////////////////////////


/**
 * A callback for assert errors in D.  The user-supplied assert handler will
 * be called if one has been supplied, otherwise an $(LREF AssertError) will be
 * thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 */
extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) nothrow
{
    if ( _assertHandler is null )
        throw staticError!AssertError(file, line);
    _assertHandler( file, line, null);
}


/**
 * A callback for assert errors in D.  The user-supplied assert handler will
 * be called if one has been supplied, otherwise an $(LREF AssertError) will be
 * thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *  msg  = An error message supplied by the user.
 */
extern (C) void onAssertErrorMsg( string file, size_t line, string msg ) nothrow
{
    if ( _assertHandler is null )
        throw staticError!AssertError(msg, file, line);
    _assertHandler( file, line, msg );
}

/**
 * A callback for null dereference errors in D.
 * The user-supplied dereference handler will be called if one has been supplied,
 * otherwise an $(LREF NullPointerError) will be thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occured.
 */
extern(C) void onNullPointerError(string file = __FILE__, size_t line = __LINE__) nothrow
{
    if (_nullDerefHandler is null)
        throw staticError!NullPointerError(file, line);
    _nullDerefHandler(file, line);
}

/**
 * A callback for unittest errors in D.  The user-supplied unittest handler
 * will be called if one has been supplied, otherwise the error will be
 * written to stderr.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *  msg  = An error message supplied by the user.
 */
extern (C) void onUnittestErrorMsg( string file, size_t line, string msg ) nothrow
{
    onAssertErrorMsg( file, line, msg );
}


///////////////////////////////////////////////////////////////////////////////
// Internal Error Callbacks
///////////////////////////////////////////////////////////////////////////////

/**
 * A callback for general array bounds errors in D. A $(LREF RangeError) will be thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF RangeError).
 */
extern (C) noreturn onRangeError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!RangeError(file, line, null);
}

/**
 * A callback for array slice out of bounds errors in D.
 *
 * Params:
 *  lower  = the lower bound of the index passed of a slice
 *  upper  = the upper bound of the index passed of a slice or the index if not a slice
 *  length = length of the array
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ArraySliceError).
 */
extern (C) noreturn onArraySliceError( size_t lower = 0, size_t upper = 0, size_t length = 0,
                              string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ArraySliceError(lower, upper, length, file, line, null);
}

/**
 * A callback for array index out of bounds errors in D.
 *
 * Params:
 *  index  = index in the array
 *  length = length of the array
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ArrayIndexError).
 */
extern (C) noreturn onArrayIndexError( size_t index = 0, size_t length = 0,
                              string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ArrayIndexError(index, length, file, line, null);
}

/**
 * A callback for finalize errors in D.  A $(LREF FinalizeError) will be thrown.
 *
 * Params:
 *  info = The TypeInfo instance for the object that failed finalization.
 *  e = The exception thrown during finalization.
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF FinalizeError).
 */
extern (C) noreturn onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow
{
    // This error is thrown during a garbage collection, so no allocation must occur while
    //  generating this object. So we use a preallocated instance
    throw staticError!FinalizeError(info, e, file, line);
}

version (D_BetterC)
{
    // When compiling with -betterC we use template functions so if they are
    // used the bodies are copied into the user's program so there is no need
    // for the D runtime during linking.

    // In the future we might want to convert all functions in this module to
    // templates even for ordinary builds instead of providing them as an
    // extern(C) library.

    noreturn onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
    {
        assert(0, "Memory allocation failed");
    }
    alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;

    noreturn onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
    {
        assert(0, "Invalid memory operation");
    }
}
else
{
    /**
     * A callback for out of memory errors in D.  An $(LREF OutOfMemoryError) will be
     * thrown.
     *
     * Throws:
     *  $(LREF OutOfMemoryError).
     */
    extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
    {
        // NOTE: Since an out of memory condition exists, no allocation must occur
        //       while generating this object.
        throw staticError!OutOfMemoryError(file, line);
    }

    extern (C) noreturn onOutOfMemoryErrorNoGC(string file = __FILE__, size_t line = __LINE__) @trusted nothrow @nogc
    {
        // suppress stacktrace until they are @nogc
        throw staticError!OutOfMemoryError(false, file, line);
    }
}

/**
 * A callback for invalid memory operations in D.  An
 * $(LREF InvalidMemoryOperationError) will be thrown.
 *
 * Throws:
 *  $(LREF InvalidMemoryOperationError).
 */
extern (C) noreturn onInvalidMemoryOperationError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
{
    // The same restriction applies as for onOutOfMemoryError. The GC is in an
    // undefined state, thus no allocation must occur while generating this object.
    throw staticError!InvalidMemoryOperationError(file, line);
}


/**
 * A callback for errors in the case of a failed fork in D.  A $(LREF ForkError) will be thrown.
 *
 * Params:
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF ConfigurationError).
 */
extern (C) noreturn onForkError( string file = __FILE__, size_t line = __LINE__ ) @trusted pure nothrow @nogc
{
    throw staticError!ForkError( file, line, null );
}

/**
 * A callback for unicode errors in D.  A $(LREF UnicodeException) will be thrown.
 *
 * Params:
 *  msg = Information about the error.
 *  idx = String index where this error was detected.
 *  file = The name of the file that signaled this error.
 *  line = The line number on which this error occurred.
 *
 * Throws:
 *  $(LREF UnicodeException).
 */
extern (C) noreturn onUnicodeError( string msg, size_t idx, string file = __FILE__, size_t line = __LINE__ ) @safe pure
{
    throw new UnicodeException( msg, idx, file, line );
}

/***********************************
 * These functions must be defined for any D program linked
 * against this library.
 */
/+
extern (C) void onAssertError(string file, size_t line);
extern (C) void onAssertErrorMsg(string file, size_t line, string msg);
extern (C) void onUnittestErrorMsg(string file, size_t line, string msg);
extern (C) void onRangeError(string file, size_t line);
extern (C) void onHiddenFuncError(Object o);
+/

/***********************************
 * Function calls to these are generated by the compiler and inserted into
 * the object code.
 */

extern (C)
{
    /* One of these three is called upon an assert() fail.
     */
    void _d_assertp(immutable(char)* file, uint line)
    {
        import core.stdc.string : strlen;
        onAssertError(file[0 .. strlen(file)], line);
    }

    void _d_assert_msg(string msg, string file, uint line)
    {
        onAssertErrorMsg(file, line, msg);
    }

    void _d_assert(string file, uint line)
    {
        onAssertError(file, line);
    }

    /* One of these three is called upon an assert() fail inside of a unittest block
     */
    void _d_unittestp(immutable(char)* file, uint line)
    {
        import core.stdc.string : strlen;
        _d_unittest(file[0 .. strlen(file)], line);
    }

    void _d_unittest_msg(string msg, string file, uint line)
    {
        onUnittestErrorMsg(file, line, msg);
    }

    void _d_unittest(string file, uint line)
    {
        _d_unittest_msg("unittest failure", file, line);
    }

    /// Called when an invalid array index/slice or associative array key is accessed
    void _d_arrayboundsp(immutable(char*) file, uint line)
    {
        import core.stdc.string : strlen;
        onRangeError(file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds(string file, uint line)
    {
        onRangeError(file, line);
    }

    /// Called when an out of range slice of an array is created
    void _d_arraybounds_slicep(immutable(char*) file, uint line, size_t lower, size_t upper, size_t length)
    {
        import core.stdc.string : strlen;
        onArraySliceError(lower, upper, length, file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds_slice(string file, uint line, size_t lower, size_t upper, size_t length)
    {
        onArraySliceError(lower, upper, length, file, line);
    }

    /// Called when an out of range array index is accessed
    void _d_arraybounds_indexp(immutable(char*) file, uint line, size_t index, size_t length)
    {
        import core.stdc.string : strlen;
        onArrayIndexError(index, length, file[0 .. strlen(file)], line);
    }

    /// ditto
    void _d_arraybounds_index(string file, uint line, size_t index, size_t length)
    {
        onArrayIndexError(index, length, file, line);
    }

    void _d_nullpointerp(immutable(char*) file, uint line)
    {
        import core.stdc.string : strlen;
        onNullPointerError(file[0 .. strlen(file)], line);
    }
}

// TLS storage shared for all errors, chaining might create circular reference
private align(2 * size_t.sizeof) void[256] _store;

// only Errors for now as those are rarely chained
package T staticError(T, Args...)(auto ref Args args)
    if (is(T : Error))
{
    // pure hack, what we actually need is @noreturn and allow to call that in pure functions
    static T get()
    {
        static assert(__traits(classInstanceSize, T) <= _store.length,
                      T.stringof ~ " is too large for staticError()");

        return cast(T) _store.ptr;
    }
    auto res = (cast(T function() @trusted pure nothrow @nogc) &get)();
    import core.lifetime : emplace;
    emplace(res, args);
    return res;
}

// Suppress traceinfo generation when the GC cannot be used.  Workaround for
// Bugzilla 14993. We should make stack traces @nogc instead.
package class SuppressTraceInfo : Throwable.TraceInfo
{
    override int opApply(scope int delegate(ref const(char[]))) const { return 0; }
    override int opApply(scope int delegate(ref size_t, ref const(char[]))) const { return 0; }
    override string toString() const { return null; }
    static SuppressTraceInfo instance() @trusted @nogc pure nothrow
    {
        static immutable SuppressTraceInfo it = new SuppressTraceInfo;
        return cast(SuppressTraceInfo)it;
    }
}
