summaryrefslogtreecommitdiffstats
path: root/source/slang/diagnostics.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-09 11:34:21 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-09 13:44:59 -0700
commitfcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch)
tree41047c94883b86ec085a81597391ce3ef557cd43 /source/slang/diagnostics.h
parent52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff)
Initial import of code.
Diffstat (limited to 'source/slang/diagnostics.h')
-rw-r--r--source/slang/diagnostics.h218
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