diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-09 11:34:21 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-09 13:44:59 -0700 |
| commit | fcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch) | |
| tree | 41047c94883b86ec085a81597391ce3ef557cd43 /source/slang/diagnostics.h | |
| parent | 52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff) | |
Initial import of code.
Diffstat (limited to 'source/slang/diagnostics.h')
| -rw-r--r-- | source/slang/diagnostics.h | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/source/slang/diagnostics.h b/source/slang/diagnostics.h new file mode 100644 index 000000000..c1559df5d --- /dev/null +++ b/source/slang/diagnostics.h @@ -0,0 +1,218 @@ +#ifndef RASTER_RENDERER_COMPILE_ERROR_H +#define RASTER_RENDERER_COMPILE_ERROR_H + +#include "../core/basic.h" + +#include "source-loc.h" +#include "token.h" + +#include "../../slang.h" + +namespace Slang +{ + namespace Compiler + { + using namespace CoreLib::Basic; + + enum class Severity + { + Note, + Warning, + Error, + Fatal, + Internal, + }; + + // TODO(tfoley): move this into a source file... + inline const char* getSeverityName(Severity severity) + { + switch (severity) + { + case Severity::Note: return "note"; + case Severity::Warning: return "warning"; + case Severity::Error: return "error"; + case Severity::Fatal: return "fatal error"; + case Severity::Internal: return "internal error"; + default: return "unknown error"; + } + } + + // A structure to be used in static data describing different + // diagnostic messages. + struct DiagnosticInfo + { + int id; + Severity severity; + char const* messageFormat; + }; + + class Diagnostic + { + public: + String Message; + CodePosition Position; + int ErrorID; + Severity severity; + + Diagnostic() + { + ErrorID = -1; + } + Diagnostic( + const String & msg, + int id, + const CodePosition & pos, + Severity severity) + : severity(severity) + { + Message = msg; + ErrorID = id; + Position = pos; + } + }; + + class Decl; + class Type; + class ExpressionType; + class ILType; + class StageAttribute; + struct TypeExp; + struct QualType; + + void printDiagnosticArg(StringBuilder& sb, char const* str); + void printDiagnosticArg(StringBuilder& sb, int val); + void printDiagnosticArg(StringBuilder& sb, CoreLib::Basic::String const& str); + void printDiagnosticArg(StringBuilder& sb, Decl* decl); + void printDiagnosticArg(StringBuilder& sb, Type* type); + void printDiagnosticArg(StringBuilder& sb, ExpressionType* type); + void printDiagnosticArg(StringBuilder& sb, TypeExp const& type); + void printDiagnosticArg(StringBuilder& sb, QualType const& type); + void printDiagnosticArg(StringBuilder& sb, TokenType tokenType); + void printDiagnosticArg(StringBuilder& sb, Token const& token); + + template<typename T> + void printDiagnosticArg(StringBuilder& sb, RefPtr<T> ptr) + { + printDiagnosticArg(sb, ptr.Ptr()); + } + + inline CodePosition const& getDiagnosticPos(CodePosition const& pos) { return pos; } + + class SyntaxNode; + class ShaderClosure; + CodePosition const& getDiagnosticPos(SyntaxNode const* syntax); + CodePosition const& getDiagnosticPos(Token const& token); + CodePosition const& getDiagnosticPos(TypeExp const& typeExp); + + template<typename T> + CodePosition getDiagnosticPos(RefPtr<T> const& ptr) + { + return getDiagnosticPos(ptr.Ptr()); + } + + struct DiagnosticArg + { + void* data; + void (*printFunc)(StringBuilder&, void*); + + template<typename T> + struct Helper + { + static void printFunc(StringBuilder& sb, void* data) { printDiagnosticArg(sb, *(T*)data); } + }; + + template<typename T> + DiagnosticArg(T const& arg) + : data((void*)&arg) + , printFunc(&Helper<T>::printFunc) + {} + }; + + class DiagnosticSink + { + public: + StringBuilder outputBuffer; +// List<Diagnostic> diagnostics; + int errorCount = 0; + + SlangDiagnosticCallback callback = nullptr; + void* callbackUserData = nullptr; + +/* + void Error(int id, const String & msg, const CodePosition & pos) + { + diagnostics.Add(Diagnostic(msg, id, pos, Severity::Error)); + errorCount++; + } + + void Warning(int id, const String & msg, const CodePosition & pos) + { + diagnostics.Add(Diagnostic(msg, id, pos, Severity::Warning)); + } +*/ + int GetErrorCount() { return errorCount; } + + void diagnoseDispatch(CodePosition const& pos, DiagnosticInfo const& info) + { + diagnoseImpl(pos, info, 0, NULL); + } + + void diagnoseDispatch(CodePosition const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0) + { + DiagnosticArg const* args[] = { &arg0 }; + diagnoseImpl(pos, info, 1, args); + } + + void diagnoseDispatch(CodePosition const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1) + { + DiagnosticArg const* args[] = { &arg0, &arg1 }; + diagnoseImpl(pos, info, 2, args); + } + + void diagnoseDispatch(CodePosition const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1, DiagnosticArg const& arg2) + { + DiagnosticArg const* args[] = { &arg0, &arg1, &arg2 }; + diagnoseImpl(pos, info, 3, args); + } + + void diagnoseDispatch(CodePosition const& pos, DiagnosticInfo const& info, DiagnosticArg const& arg0, DiagnosticArg const& arg1, DiagnosticArg const& arg2, DiagnosticArg const& arg3) + { + DiagnosticArg const* args[] = { &arg0, &arg1, &arg2, &arg3 }; + diagnoseImpl(pos, info, 4, args); + } + + template<typename P, typename... Args> + void diagnose(P const& pos, DiagnosticInfo const& info, Args const&... args ) + { + diagnoseDispatch(getDiagnosticPos(pos), info, args...); + } + + void diagnoseImpl(CodePosition const& pos, DiagnosticInfo const& info, int argCount, DiagnosticArg const* const* args); + }; + + namespace Diagnostics + { +#define DIAGNOSTIC(id, severity, name, messageFormat) extern const DiagnosticInfo name; +#include "diagnostic-defs.h" + } + } +} + +#ifdef _DEBUG +#define SLANG_INTERNAL_ERROR(sink, pos) \ + (sink)->diagnose(Slang::Compiler::CodePosition(__LINE__, 0, 0, __FILE__), Slang::Compiler::Diagnostics::internalCompilerError) +#define SLANG_UNIMPLEMENTED(sink, pos, what) \ + (sink)->diagnose(Slang::Compiler::CodePosition(__LINE__, 0, 0, __FILE__), Slang::Compiler::Diagnostics::unimplemented, what) + +#define SLANG_UNREACHABLE(msg) do { assert(!"ureachable code:" msg); exit(1); } while(0) +#else +#define SLANG_INTERNAL_ERROR(sink, pos) \ + (sink)->diagnose(pos, Slang::Compiler::Diagnostics::internalCompilerError) +#define SLANG_UNIMPLEMENTED(sink, pos, what) \ + (sink)->diagnose(pos, Slang::Compiler::Diagnostics::unimplemented, what) + +// TODO: find something that will perform better +#define SLANG_UNREACHABLE(msg) exit(1) +#endif + +#endif |
