summaryrefslogtreecommitdiffstats
path: root/source/core/slang-signal.cpp
blob: 9641fe5f73b32900fddaabb1640e8b9e905ee53d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "slang-signal.h"

#include "slang-exception.h"

#include "stdio.h"

namespace Slang
{

static const char* _getSignalTypeAsText(SignalType type)
{
    switch (type)
    {
        case SignalType::AssertFailure:     return "assert failure";
        case SignalType::Unimplemented:     return "unimplemented";
        case SignalType::Unreachable:       return "hit unreachable code";
        case SignalType::Unexpected:        return "unexpected";
        case SignalType::InvalidOperation:  return "invalid operation";
        case SignalType::AbortCompilation:  return "abort compilation";
        default:                            return "unhandled";
    }
}

String _getMessage(SignalType type, char const* message)
{
    StringBuilder buf;
    const char* const typeText = _getSignalTypeAsText(type);
    buf << typeText;
    if (message)
    {
        buf << ": " << message;
    }
    
    return buf.ProduceString();
}

// One point of having as a single function is a choke point both for handling (allowing different
// handling scenarios) as well as a choke point to set a breakpoint to catch 'signal' types
SLANG_RETURN_NEVER void handleSignal(SignalType type, char const* message)
{
    StringBuilder buf;
    const char*const typeText = _getSignalTypeAsText(type);
    buf << typeText << ": " << message;

    // Can be useful to enable during debug when problem is on CI
    if (false)
    {
        printf("%s\n", _getMessage(type, message).getBuffer());
    }

#if SLANG_HAS_EXCEPTIONS
    switch (type)
    {
        case SignalType::InvalidOperation:  throw InvalidOperationException(_getMessage(type, message));
        case SignalType::AbortCompilation:  throw AbortCompilationException();
        default:    throw InternalError(_getMessage(type, message));
    }
#else
    // Attempt to drop out into the debugger. If a debugger isn't attached this will likely crash - which is probably the best
    // we can do.
    
    SLANG_BREAKPOINT(0);

    // 'panic'. Exit with an error code as we can't throw or catch.
    exit(-1);
#endif
}

}