summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tim.foley.is@gmail.com>2017-07-19 18:52:38 -0700
committerGitHub <noreply@github.com>2017-07-19 18:52:38 -0700
commitf07c01ceb012b9b325a8ecebd12cdd5797d8d5b3 (patch)
tree0b93a109d51e6565560ad785519a863386490e2a /source
parenta2b8b4c20632d79721052abd232fe2d1bdf2700d (diff)
parent3f48e1c0d84bf4909954154ad147559656e87516 (diff)
Merge pull request #128 from tfoleyNV/improve-failure-modes
Try to improve handling of failures during compilation
Diffstat (limited to 'source')
-rw-r--r--source/core/common.h29
-rw-r--r--source/core/exception.h16
-rw-r--r--source/core/slang-string.cpp8
-rw-r--r--source/core/slang-string.h4
-rw-r--r--source/core/smart-pointer.h5
-rw-r--r--source/slang/check.cpp217
-rw-r--r--source/slang/compiler.cpp63
-rw-r--r--source/slang/diagnostic-defs.h10
-rw-r--r--source/slang/diagnostics.cpp2
-rw-r--r--source/slang/diagnostics.h6
-rw-r--r--source/slang/emit.cpp123
-rw-r--r--source/slang/lexer.cpp20
-rw-r--r--source/slang/lower.cpp77
-rw-r--r--source/slang/options.cpp2
-rw-r--r--source/slang/parameter-binding.cpp30
-rw-r--r--source/slang/parser.cpp9
-rw-r--r--source/slang/preprocessor.cpp11
-rw-r--r--source/slang/reflection.cpp72
-rw-r--r--source/slang/slang-stdlib.cpp4
-rw-r--r--source/slang/slang.cpp14
-rw-r--r--source/slang/syntax-base-defs.h2
-rw-r--r--source/slang/syntax.cpp34
-rw-r--r--source/slang/token.cpp2
-rw-r--r--source/slang/type-layout.cpp29
24 files changed, 334 insertions, 455 deletions
diff --git a/source/core/common.h b/source/core/common.h
index 25e85dc66..f0f6902d1 100644
--- a/source/core/common.h
+++ b/source/core/common.h
@@ -34,6 +34,35 @@ namespace Slang
v0 = _Move(v1);
v1 = _Move(tmp);
}
+
+#ifdef _MSC_VER
+#define SLANG_RETURN_NEVER __declspec(noreturn)
+#else
+#efine SLANG_RETURN_NEVER /* empty */
+#endif
+
+ SLANG_RETURN_NEVER void signalUnexpectedError(char const* message);
}
+#define SLANG_UNEXPECTED(reason) \
+ Slang::signalUnexpectedError("unexpected: " reason)
+
+#define SLANG_UNIMPLEMENTED_X(what) \
+ Slang::signalUnexpectedError("unimplemented: " what)
+
+#define SLANG_UNREACHABLE(msg) \
+ Slang::signalUnexpectedError("unreachable code executed: " msg)
+
+#ifdef _DEBUG
+#define SLANG_EXPECT(VALUE, MSG) if(VALUE) {} else Slang::signalUnexpectedError("assertion failed: '" MSG "'")
+#define SLANG_ASSERT(VALUE) SLANG_EXPECT(VALUE, #VALUE)
+#else
+#define SLANG_EXPECT(VALUE, MSG) do {} while(0)
+#define SLANG_ASSERT(VALUE) do {} while(0)
+#endif
+
+#define SLANG_RELEASE_ASSERT(VALUE) if(VALUE) {} else Slang::signalUnexpectedError("assertion failed")
+#define SLANG_RELEASE_EXPECT(VALUE, WHAT) if(VALUE) {} else SLANG_UNEXPECTED(WHAT)
+
+
#endif
diff --git a/source/core/exception.h b/source/core/exception.h
index dc674de7f..aedb62add 100644
--- a/source/core/exception.h
+++ b/source/core/exception.h
@@ -111,12 +111,16 @@ namespace Slang
}
};
- #define SLANG_UNEXPECTED(reason) \
- throw Slang::Exception("unexpected: " reason)
-
- #define SLANG_UNIMPLEMENTED_X(what) \
- throw Slang::NotImplementedException("unimplemented: " what)
-
+ class InternalError : public Exception
+ {
+ public:
+ InternalError()
+ {}
+ InternalError(const String & message)
+ : Exception(message)
+ {
+ }
+ };
}
#endif \ No newline at end of file
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index 8938db595..459396f69 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -3,6 +3,14 @@
namespace Slang
{
+ // TODO: this belongs in a different file:
+
+ SLANG_RETURN_NEVER void signalUnexpectedError(char const* message)
+ {
+ throw InternalError(message);
+ }
+
+
// OSString
OSString::OSString()
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 3c1b48e8c..552afe833 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -1,8 +1,10 @@
#ifndef FUNDAMENTAL_LIB_STRING_H
#define FUNDAMENTAL_LIB_STRING_H
+
#include <string.h>
#include <cstdlib>
#include <stdio.h>
+
#include "smart-pointer.h"
#include "common.h"
#include "hash.h"
@@ -80,7 +82,7 @@ namespace Slang
static StringRepresentation* createWithCapacityAndLength(UInt capacity, UInt length)
{
- assert(capacity >= length);
+ SLANG_ASSERT(capacity >= length);
void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
StringRepresentation* obj = new(allocation) StringRepresentation();
obj->capacity = capacity;
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index fea149e06..87cb40d70 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -1,6 +1,7 @@
#ifndef FUNDAMENTAL_LIB_SMART_POINTER_H
#define FUNDAMENTAL_LIB_SMART_POINTER_H
+#include "common.h"
#include "type-traits.h"
#include <assert.h>
@@ -36,7 +37,7 @@ namespace Slang
void releaseReference()
{
- assert(referenceCount != 0);
+ SLANG_ASSERT(referenceCount != 0);
if(--referenceCount == 0)
{
delete this;
@@ -45,7 +46,7 @@ namespace Slang
bool isUniquelyReferenced()
{
- assert(referenceCount != 0);
+ SLANG_ASSERT(referenceCount != 0);
return referenceCount == 1;
}
};
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 26d28d495..ccc0fb087 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -166,7 +166,7 @@ namespace Slang
RefPtr<ExpressionSyntaxNode> originalExpr)
{
auto ptrLikeType = base->Type->As<PointerLikeType>();
- assert(ptrLikeType);
+ SLANG_ASSERT(ptrLikeType);
auto derefExpr = new DerefExpr();
derefExpr->Position = originalExpr->Position;
@@ -228,7 +228,7 @@ namespace Slang
RefPtr<ExpressionSyntaxNode> ResolveOverloadedExpr(RefPtr<OverloadedExpr> overloadedExpr, LookupMask mask)
{
auto lookupResult = overloadedExpr->lookupResult2;
- assert(lookupResult.isValid() && lookupResult.isOverloaded());
+ SLANG_RELEASE_ASSERT(lookupResult.isValid() && lookupResult.isOverloaded());
// Take the lookup result we had, and refine it based on what is expected in context.
lookupResult = refineLookup(lookupResult, mask);
@@ -840,7 +840,7 @@ namespace Slang
auto fromInfo = GetBaseTypeConversionInfo(fromBasicType->BaseType);
// We expect identical types to have been dealt with already.
- assert(toInfo.kind != fromInfo.kind || toInfo.rank != fromInfo.rank);
+ SLANG_ASSERT(toInfo.kind != fromInfo.kind || toInfo.rank != fromInfo.rank);
if (outToExpr)
*outToExpr = CreateImplicitCastExpr(toType, fromExpr);
@@ -1512,7 +1512,7 @@ namespace Slang
void ValidateFunctionRedeclaration(FunctionSyntaxNode* funcDecl)
{
auto parentDecl = funcDecl->ParentDecl;
- assert(parentDecl);
+ SLANG_RELEASE_ASSERT(parentDecl);
if (!parentDecl) return;
// Look at previously-declared functions with the same name,
@@ -2489,77 +2489,6 @@ namespace Slang
return Coerce(type, expr);
}
- // Resolve a call to a function, represented here
- // by a symbol with a `FuncType` type.
- RefPtr<ExpressionSyntaxNode> ResolveFunctionApp(
- RefPtr<FuncType> funcType,
- InvokeExpressionSyntaxNode* /*appExpr*/)
- {
- // TODO(tfoley): Actual checking logic needs to go here...
-#if 0
- auto& args = appExpr->Arguments;
- List<RefPtr<ParameterSyntaxNode>> params;
- RefPtr<ExpressionType> resultType;
- if (auto funcDeclRef = funcType->declRef)
- {
- EnsureDecl(funcDeclRef.getDecl());
-
- params = funcDeclRef->GetParameters().ToArray();
- resultType = funcDecl->ReturnType;
- }
- else if (auto funcSym = funcType->Func)
- {
- auto funcDecl = funcSym->SyntaxNode;
- EnsureDecl(funcDecl);
-
- params = funcDecl->GetParameters().ToArray();
- resultType = funcDecl->ReturnType;
- }
- else if (auto componentFuncSym = funcType->Component)
- {
- auto componentFuncDecl = componentFuncSym->Implementations.First()->SyntaxNode;
- params = componentFuncDecl->GetParameters().ToArray();
- resultType = componentFuncDecl->Type;
- }
-
- auto argCount = args.Count();
- auto paramCount = params.Count();
- if (argCount != paramCount)
- {
- getSink()->diagnose(appExpr, Diagnostics::unimplemented, "wrong number of arguments for call");
- appExpr->Type = ExpressionType::Error;
- return appExpr;
- }
-
- for (int ii = 0; ii < argCount; ++ii)
- {
- auto arg = args[ii];
- auto param = params[ii];
-
- arg = CoerceExprToType(arg, param->Type);
-
- args[ii] = arg;
- }
-
- assert(resultType);
- appExpr->Type = resultType;
- return appExpr;
-#else
- throw "unimplemented";
-#endif
- }
-
- // Resolve a constructor call, formed by apply a type to arguments
- RefPtr<ExpressionSyntaxNode> ResolveConstructorApp(
- RefPtr<ExpressionType> type,
- InvokeExpressionSyntaxNode* appExpr)
- {
- // TODO(tfoley): Actual checking logic needs to go here...
-
- appExpr->Type = QualType(type);
- return appExpr;
- }
-
RefPtr<ExpressionSyntaxNode> visitParenExpr(ParenExpr* expr)
{
auto base = expr->base;
@@ -2794,7 +2723,7 @@ namespace Slang
return left;
else
{
- assert(rightFlavor > leftFlavor);
+ SLANG_ASSERT(rightFlavor > leftFlavor);
return right;
}
}
@@ -2894,7 +2823,7 @@ namespace Slang
continue;
auto cType = c.val.As<ExpressionType>();
- assert(cType.Ptr());
+ SLANG_RELEASE_ASSERT(cType.Ptr());
if (!type)
{
@@ -2933,7 +2862,7 @@ namespace Slang
continue;
auto cVal = c.val.As<IntVal>();
- assert(cVal.Ptr());
+ SLANG_RELEASE_ASSERT(cVal.Ptr());
if (!val)
{
@@ -2982,104 +2911,6 @@ namespace Slang
solvedSubst->args = args;
return solvedSubst;
-
-
-#if 0
- List<RefPtr<Val>> solvedArgs;
- for (auto varArg : varSubst->args)
- {
- if (auto typeVar = dynamic_cast<ConstraintVarType*>(varArg.Ptr()))
- {
- RefPtr<ExpressionType> type = nullptr;
- for (auto& c : system->constraints)
- {
- if (c.decl != typeVar->declRef.getDecl())
- continue;
-
- auto cType = c.val.As<ExpressionType>();
- assert(cType.Ptr());
-
- if (!type)
- {
- type = cType;
- }
- else
- {
- if (!type->Equals(cType))
- {
- // failure!
- return nullptr;
- }
- }
-
- c.satisfied = true;
- }
-
- if (!type)
- {
- // failure!
- return nullptr;
- }
- solvedArgs.Add(type);
- }
- else if (auto valueVar = dynamic_cast<ConstraintVarInt*>(varArg.Ptr()))
- {
- // TODO(tfoley): maybe support more than integers some day?
- RefPtr<IntVal> val = nullptr;
- for (auto& c : system->constraints)
- {
- if (c.decl != valueVar->declRef.getDecl())
- continue;
-
- auto cVal = c.val.As<IntVal>();
- assert(cVal.Ptr());
-
- if (!val)
- {
- val = cVal;
- }
- else
- {
- if (val->value != cVal->value)
- {
- // failure!
- return nullptr;
- }
- }
-
- c.satisfied = true;
- }
-
- if (!val)
- {
- // failure!
- return nullptr;
- }
- solvedArgs.Add(val);
- }
- else
- {
- // ignore anything that isn't a generic parameter
- }
- }
-
- // Make sure we haven't constructed any spurious constraints
- // that we aren't able to satisfy:
- for (auto c : system->constraints)
- {
- if (!c.satisfied)
- {
- return nullptr;
- }
- }
-
- RefPtr<Substitutions> newSubst = new Substitutions();
- newSubst->genericDecl = varSubst->genericDecl;
- newSubst->outer = varSubst->outer;
- newSubst->args = solvedArgs;
- return newSubst;
-
-#endif
}
//
@@ -3225,7 +3056,7 @@ namespace Slang
break;
default:
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unknown flavor of overload candidate");
break;
}
@@ -3244,7 +3075,7 @@ namespace Slang
}
else
{
- assert(argCount > paramCounts.allowed);
+ SLANG_ASSERT(argCount > paramCounts.allowed);
if (!isRewriteMode())
{
getSink()->diagnose(context.appExpr, Diagnostics::tooManyArguments, argCount, paramCounts.allowed);
@@ -3376,13 +3207,13 @@ namespace Slang
return TryCheckGenericOverloadCandidateTypes(context, candidate);
default:
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unknown flavor of overload candidate");
break;
}
// Note(tfoley): We might have fewer arguments than parameters in the
// case where one or more parameters had defaults.
- assert(argCount <= params.Count());
+ SLANG_RELEASE_ASSERT(argCount <= params.Count());
for (UInt ii = 0; ii < argCount; ++ii)
{
@@ -3446,13 +3277,13 @@ namespace Slang
auto baseDeclRefExpr = baseExpr.As<DeclRefExpr>();
if (!baseDeclRefExpr)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), baseExpr, "expected a reference to a generic declaration");
return CreateErrorExpr(appExpr.Ptr());
}
auto baseGenericRef = baseDeclRefExpr->declRef.As<GenericDecl>();
if (!baseGenericRef)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), baseExpr, "expected a reference to a generic declaration");
return CreateErrorExpr(appExpr.Ptr());
}
@@ -3544,7 +3375,7 @@ namespace Slang
break;
default:
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), context.appExpr, "unknown overload candidate flavor");
break;
}
}
@@ -3614,7 +3445,7 @@ namespace Slang
// isn't transitive). Therefore we confirm that we either chose to keep
// this candidate (in which case filtering is okay), or we didn't filter
// anything.
- assert(keepThisCandidate || !anyFiltered);
+ SLANG_ASSERT(keepThisCandidate || !anyFiltered);
}
else if(context.bestCandidate)
{
@@ -3802,7 +3633,7 @@ namespace Slang
return false;
// Their arguments must unify
- assert(fst->args.Count() == snd->args.Count());
+ SLANG_RELEASE_ASSERT(fst->args.Count() == snd->args.Count());
UInt argCount = fst->args.Count();
for (UInt aa = 0; aa < argCount; ++aa)
{
@@ -3997,7 +3828,7 @@ namespace Slang
// We expect/require that the result of unification is such that
// the target types are now equal
- assert(GetTargetType(extDeclRef)->Equals(type));
+ SLANG_ASSERT(GetTargetType(extDeclRef)->Equals(type));
return extDeclRef;
}
@@ -4232,7 +4063,7 @@ namespace Slang
else if (auto overloadedExpr = funcExpr.As<OverloadedExpr>())
{
auto lookupResult = overloadedExpr->lookupResult2;
- assert(lookupResult.isOverloaded());
+ SLANG_RELEASE_ASSERT(lookupResult.isOverloaded());
for(auto item : lookupResult.items)
{
AddDeclRefOverloadCandidates(item, context);
@@ -4287,8 +4118,8 @@ namespace Slang
// signature
if( parentGenericDeclRef )
{
- assert(declRef.substitutions);
- assert(declRef.substitutions->genericDecl == parentGenericDeclRef.getDecl());
+ SLANG_RELEASE_ASSERT(declRef.substitutions);
+ SLANG_RELEASE_ASSERT(declRef.substitutions->genericDecl == parentGenericDeclRef.getDecl());
sb << "<";
bool first = true;
@@ -4827,25 +4658,25 @@ namespace Slang
RefPtr<ExpressionSyntaxNode> visitDerefExpr(DerefExpr* expr)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "should not appear in input syntax");
return expr;
}
RefPtr<ExpressionSyntaxNode> visitSwizzleExpr(SwizzleExpr* expr)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "should not appear in input syntax");
return expr;
}
RefPtr<ExpressionSyntaxNode> visitOverloadedExpr(OverloadedExpr* expr)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "should not appear in input syntax");
return expr;
}
RefPtr<ExpressionSyntaxNode> visitAggTypeCtorExpr(AggTypeCtorExpr* expr)
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "should not appear in input syntax");
return expr;
}
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 85e78e85b..e16b9dec7 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -188,12 +188,21 @@ namespace Slang
}
#ifdef _WIN32
- void* GetD3DCompilerDLL()
+ HMODULE loadD3DCompilerDLL(CompileRequest* request)
+ {
+ char const* libraryName = "d3dcompiler_47";
+ HMODULE d3dCompiler = LoadLibraryA(libraryName);
+ if (!d3dCompiler)
+ {
+ request->mSink.diagnose(CodePosition(), Diagnostics::failedToLoadDynamicLibrary, libraryName);
+ }
+ return d3dCompiler;
+ }
+
+ HMODULE getD3DCompilerDLL(CompileRequest* request)
{
// TODO(tfoley): let user specify version of d3dcompiler DLL to use.
- static HMODULE d3dCompiler = LoadLibraryA("d3dcompiler_47");
- // TODO(tfoley): handle case where we can't find it gracefully
- assert(d3dCompiler);
+ static HMODULE d3dCompiler = loadD3DCompilerDLL(request);
return d3dCompiler;
}
@@ -203,11 +212,13 @@ namespace Slang
static pD3DCompile D3DCompile_ = nullptr;
if (!D3DCompile_)
{
- HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL();
- assert(d3dCompiler);
+ HMODULE d3dCompiler = getD3DCompilerDLL(entryPoint->compileRequest);
+ if (!d3dCompiler)
+ return List<uint8_t>();
D3DCompile_ = (pD3DCompile)GetProcAddress(d3dCompiler, "D3DCompile");
- assert(D3DCompile_);
+ if (!D3DCompile_)
+ return List<uint8_t>();
}
auto hlslCode = emitHLSLForEntryPoint(entryPoint);
@@ -274,18 +285,20 @@ namespace Slang
#endif
String dissassembleDXBC(
- CompileRequest*,
+ CompileRequest* compileRequest,
void const* data,
size_t size)
{
static pD3DDisassemble D3DDisassemble_ = nullptr;
if (!D3DDisassemble_)
{
- HMODULE d3dCompiler = (HMODULE)GetD3DCompilerDLL();
- assert(d3dCompiler);
+ HMODULE d3dCompiler = getD3DCompilerDLL(compileRequest);
+ if (!d3dCompiler)
+ return String();
D3DDisassemble_ = (pD3DDisassemble)GetProcAddress(d3dCompiler, "D3DDisassemble");
- assert(D3DDisassemble_);
+ if (!D3DDisassemble_)
+ return String();
}
if (!data || !size)
@@ -351,12 +364,21 @@ namespace Slang
}
#endif
- HMODULE getGLSLCompilerDLL()
+ HMODULE loadGLSLCompilerDLL(CompileRequest* request)
{
+ char const* libraryName = "slang-glslang";
// TODO(tfoley): let user specify version of glslang DLL to use.
- static HMODULE glslCompiler = LoadLibraryA("slang-glslang");
- // TODO(tfoley): handle case where we can't find it gracefully
- assert(glslCompiler);
+ HMODULE glslCompiler = LoadLibraryA(libraryName);
+ if (!glslCompiler)
+ {
+ request->mSink.diagnose(CodePosition(), Diagnostics::failedToLoadDynamicLibrary, libraryName);
+ }
+ return glslCompiler;
+ }
+
+ HMODULE getGLSLCompilerDLL(CompileRequest* request)
+ {
+ static HMODULE glslCompiler = loadGLSLCompilerDLL(request);
return glslCompiler;
}
@@ -369,11 +391,13 @@ namespace Slang
static glslang_CompileFunc glslang_compile = nullptr;
if (!glslang_compile)
{
- HMODULE glslCompiler = getGLSLCompilerDLL();
- assert(glslCompiler);
+ HMODULE glslCompiler = getGLSLCompilerDLL(slangCompileRequest);
+ if (!glslCompiler)
+ return 1;
glslang_compile = (glslang_CompileFunc)GetProcAddress(glslCompiler, "glslang_compile");
- assert(glslang_compile);
+ if (!glslang_compile)
+ return 1;
}
String diagnosticOutput;
@@ -561,7 +585,8 @@ namespace Slang
break;
default:
- throw "unimplemented";
+ SLANG_UNEXPECTED("unhandled code generation target");
+ break;
}
return result;
diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h
index 17291d1ad..32385bd24 100644
--- a/source/slang/diagnostic-defs.h
+++ b/source/slang/diagnostic-defs.h
@@ -47,6 +47,7 @@ DIAGNOSTIC( 1, Error, cannotOpenFile, "cannot open file '$0'.")
DIAGNOSTIC( 2, Error, cannotFindFile, "cannot find file '$0'.")
DIAGNOSTIC( 2, Error, unsupportedCompilerMode, "unsupported compiler mode.")
DIAGNOSTIC( 4, Error, cannotWriteOutputFile, "cannot write output file '$0'.")
+DIAGNOSTIC( 5, Error, failedToLoadDynamicLibrary, "failed to load dynamic library '$0'")
//
// 1xxxx - Lexical anaylsis
@@ -102,6 +103,7 @@ DIAGNOSTIC(15403, Error, expectedTokenInMacroParameters, "expected '$0' in macro
// 155xx - macro expansion
DIAGNOSTIC(15500, Warning, expectedTokenInMacroArguments, "expected '$0' in macro invocation")
+DIAGNOSTIC(15501, Error, wrongNumberOfArgumentsToMacro, "wrong number of arguments to macro (expected $0, got $1)")
// 159xx - user-defined error/warning
DIAGNOSTIC(15900, Error, userDefinedError, "#error: $0")
@@ -298,6 +300,10 @@ DIAGNOSTIC(40002, Error, invalidBindingValue, "binding location '$0' is out of v
DIAGNOSTIC(40003, Error, bindingExceedsLimit, "binding location '$0' assigned to component '$1' exceeds maximum limit.")
DIAGNOSTIC(40004, Error, bindingAlreadyOccupiedByModule, "DescriptorSet ID '$0' is already occupied by module instance '$1'.")
DIAGNOSTIC(40005, Error, topLevelModuleUsedWithoutSpecifyingBinding, "top level module '$0' is being used without specifying binding location. Use [Binding: \"index\"] attribute to provide a binding location.")
+
+
+DIAGNOSTIC(49999, Error, unknownSystemValueSemantic, "unknown system-value semantic '$0'")
+
//
// 5xxxx - Target code generation.
//
@@ -339,7 +345,9 @@ DIAGNOSTIC(51092, Error, stageDoesntHaveInputWorld, "'$0' doesn't appear to have
// 99999 - Internal compiler errors, and not-yet-classified diagnostics.
+DIAGNOSTIC(99999, Internal, unimplemented, "unimplemented: $0")
+DIAGNOSTIC(99999, Internal, unexpected, "uuexpected: $0")
DIAGNOSTIC(99999, Internal, internalCompilerError, "internal compiler error")
-DIAGNOSTIC(99999, Internal, unimplemented, "unimplemented feature: $0")
+DIAGNOSTIC(99999, Error, compilationAborted, "compilation aborted due to internal error");
#undef DIAGNOSTIC
diff --git a/source/slang/diagnostics.cpp b/source/slang/diagnostics.cpp
index 870e6d172..d23f2bd16 100644
--- a/source/slang/diagnostics.cpp
+++ b/source/slang/diagnostics.cpp
@@ -100,7 +100,7 @@ static void formatDiagnosticMessage(StringBuilder& sb, char const* format, int a
if (!*spanEnd)
return;
- assert(*spanEnd == '$');
+ SLANG_API(*spanEnd == '$');
spanEnd++;
int d = *spanEnd++;
switch (d)
diff --git a/source/slang/diagnostics.h b/source/slang/diagnostics.h
index 988cb742b..f88bf460e 100644
--- a/source/slang/diagnostics.h
+++ b/source/slang/diagnostics.h
@@ -206,15 +206,15 @@ namespace Slang
#define SLANG_UNIMPLEMENTED(sink, pos, what) \
(sink)->diagnose(Slang::CodePosition(__LINE__, 0, 0, __FILE__), Slang::Diagnostics::unimplemented, what)
-#define SLANG_UNREACHABLE(msg) do { assert(!"ureachable code:" msg); throw 0; } while(0)
#else
#define SLANG_INTERNAL_ERROR(sink, pos) \
(sink)->diagnose(pos, Slang::Diagnostics::internalCompilerError)
#define SLANG_UNIMPLEMENTED(sink, pos, what) \
(sink)->diagnose(pos, Slang::Diagnostics::unimplemented, what)
-// TODO: find something that will perform better
-#define SLANG_UNREACHABLE(msg) exit(1)
#endif
+#define SLANG_DIAGNOSE_UNEXPECTED(sink, pos, message) \
+ (sink)->diagnose(pos, Slang::Diagnostics::unexpected, message)
+
#endif
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 2f009bb81..4754578b3 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -79,7 +79,6 @@ void requireGLSLVersion(
ProfileVersion version)
{
auto profile = entryPoint->profile;
- auto currentVersion = profile.GetVersion();
if (profile.getFamily() == ProfileFamily::GLSL)
{
// Check if this profile is newer
@@ -105,8 +104,8 @@ static String getStringOrIdentifierTokenValue(
switch(token.Type)
{
default:
- assert(!"unexpected");
- return "";
+ SLANG_UNEXPECTED("needed an identifier or string literal");
+ break;
case TokenType::Identifier:
return token.Content;
@@ -600,7 +599,7 @@ struct EmitVisitor
{
Emit("\n");
}
- assert(sourceLocation.Line == context->shared->loc.Line);
+ SLANG_RELEASE_ASSERT(sourceLocation.Line == context->shared->loc.Line);
}
else
{
@@ -674,6 +673,10 @@ struct EmitVisitor
emit(token.Content);
}
+ DiagnosticSink* getSink()
+ {
+ return &context->shared->entryPoint->compileRequest->mSink;
+ }
//
// Types
@@ -691,7 +694,7 @@ struct EmitVisitor
}
else
{
- assert(!"unimplemented");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unknown type of integer constant value");
}
}
@@ -723,7 +726,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unknown declarator flavor");
break;
}
}
@@ -742,8 +745,9 @@ struct EmitVisitor
case BaseType::Int: Emit("i"); break;
case BaseType::UInt: Emit("u"); break;
case BaseType::Bool: Emit("b"); break;
+ case BaseType::Double: Emit("d"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled GLSL type prefix");
break;
}
}
@@ -757,7 +761,7 @@ struct EmitVisitor
}
else
{
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled GLSL type prefix");
}
}
@@ -786,7 +790,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled resource access mode");
break;
}
@@ -798,7 +802,7 @@ struct EmitVisitor
case TextureType::ShapeCube: Emit("TextureCube"); break;
case TextureType::ShapeBuffer: Emit("Buffer"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled resource shape");
break;
}
@@ -830,7 +834,7 @@ struct EmitVisitor
case TextureType::ShapeCube: Emit("Cube"); break;
case TextureType::ShapeBuffer: Emit("Buffer"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled resource shape");
break;
}
@@ -876,7 +880,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled code generation target");
break;
}
}
@@ -891,7 +895,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "this target should see combined texture-sampler types");
break;
}
}
@@ -910,7 +914,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "this target should see GLSL image types");
break;
}
}
@@ -959,8 +963,9 @@ struct EmitVisitor
case BaseType::Float: Emit("float"); break;
case BaseType::UInt: Emit("uint"); break;
case BaseType::Bool: Emit("bool"); break;
+ case BaseType::Double: Emit("double"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled scalar type");
break;
}
@@ -992,7 +997,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled code generation target");
break;
}
@@ -1030,7 +1035,7 @@ struct EmitVisitor
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled code generation target");
break;
}
@@ -1070,7 +1075,7 @@ struct EmitVisitor
case SamplerStateType::Flavor::SamplerState: Emit("SamplerState"); break;
case SamplerStateType::Flavor::SamplerComparisonState: Emit("SamplerComparisonState"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled sampler state flavor");
break;
}
break;
@@ -1081,7 +1086,7 @@ struct EmitVisitor
case SamplerStateType::Flavor::SamplerState: Emit("sampler"); break;
case SamplerStateType::Flavor::SamplerComparisonState: Emit("samplerShadow"); break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled sampler state flavor");
break;
}
break;
@@ -1170,7 +1175,10 @@ struct EmitVisitor
{
if (!typeExp.type || typeExp.type->As<ErrorType>())
{
- assert(typeExp.exp);
+ if (!typeExp.exp)
+ {
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unresolved type expression should have expression part");
+ }
EDeclarator nameDeclarator;
nameDeclarator.flavor = EDeclarator::Flavor::Name;
@@ -1344,7 +1352,7 @@ struct EmitVisitor
}
else
{
- assert(postOp);
+ SLANG_ASSERT(postOp);
EmitExprWithPrecedence(arg, leftSide(outerPrec, prec));
}
@@ -1394,7 +1402,7 @@ struct EmitVisitor
switch(context->shared->target)
{
default:
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled code generation target");
return false;
case CodeGenTarget::GLSL: return targetName == "glsl";
@@ -1877,7 +1885,7 @@ struct EmitVisitor
continue;
}
- assert(cursor != end);
+ SLANG_RELEASE_ASSERT(cursor != end);
char d = *cursor++;
@@ -1888,7 +1896,7 @@ struct EmitVisitor
{
// Simple case: emit one of the direct arguments to the call
UInt argIndex = d - '0';
- assert((0 <= argIndex) && (argIndex < argCount));
+ SLANG_RELEASE_ASSERT((0 <= argIndex) && (argIndex < argCount));
Emit("(");
EmitExpr(callExpr->Arguments[argIndex]);
Emit(")");
@@ -1906,7 +1914,7 @@ struct EmitVisitor
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
break;
@@ -1914,7 +1922,7 @@ struct EmitVisitor
// If we are calling a D3D texturing operation in the form t.Foo(s, ...),
// then this form will pair up the t and s arguments as needed for a GLSL
// texturing operation.
- assert(argCount > 0);
+ SLANG_RELEASE_ASSERT(argCount > 0);
if (auto memberExpr = callExpr->FunctionExpr.As<MemberExpressionSyntaxNode>())
{
auto base = memberExpr->BaseExpression;
@@ -1938,13 +1946,13 @@ struct EmitVisitor
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
break;
@@ -1997,13 +2005,13 @@ struct EmitVisitor
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
}
break;
@@ -2013,7 +2021,7 @@ struct EmitVisitor
// where `t` is a `Texture*<T>`, then this is the step where we try to
// properly swizzle the output of the equivalent GLSL call into the right
// shape.
- assert(argCount > 0);
+ SLANG_RELEASE_ASSERT(argCount > 0);
if (auto memberExpr = callExpr->FunctionExpr.As<MemberExpressionSyntaxNode>())
{
auto base = memberExpr->BaseExpression;
@@ -2043,19 +2051,19 @@ struct EmitVisitor
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
}
break;
default:
- assert(!"unexpected");
+ SLANG_UNEXPECTED("bad format in intrinsic definition");
break;
}
}
@@ -2261,7 +2269,7 @@ struct EmitVisitor
}
else
{
- assert(!"unimplemented");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), litExpr, "unhandled type for integer literal");
}
Emit(litExpr->integerValue);
Emit(suffix);
@@ -2283,7 +2291,7 @@ struct EmitVisitor
}
else
{
- assert(!"unimplemented");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), litExpr, "unhandled type for floating-point literal");
}
Emit(litExpr->floatingPointValue);
Emit(suffix);
@@ -2296,7 +2304,7 @@ struct EmitVisitor
emitStringLiteral(litExpr->stringValue);
break;
default:
- assert(!"unreachable");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), litExpr, "unhandled kind of literal expression");
break;
}
if(needClose) Emit(")");
@@ -2588,8 +2596,7 @@ struct EmitVisitor
return;
}
- throw "unimplemented";
-
+ SLANG_UNEXPECTED("unhandled statement kind");
}
//
@@ -2716,7 +2723,7 @@ struct EmitVisitor
{
// Note(tfoley): any `typedef`s should already have been filtered
// out if we are generating GLSL.
- assert(context->shared->target != CodeGenTarget::GLSL);
+ SLANG_RELEASE_ASSERT(context->shared->target != CodeGenTarget::GLSL);
Emit("typedef ");
EmitType(decl->Type, decl->Name.Content);
@@ -2968,7 +2975,7 @@ struct EmitVisitor
}
else
{
- assert(!"unimplemented");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), semantic->Position, "unhandled kind of semantic");
}
}
@@ -3116,7 +3123,7 @@ struct EmitVisitor
if (byteOffsetInRegister != 0)
{
// The value had better occupy a whole number of components.
- assert(byteOffsetInRegister % componentSize == 0);
+ SLANG_RELEASE_ASSERT(byteOffsetInRegister % componentSize == 0);
size_t startComponent = byteOffsetInRegister / componentSize;
@@ -3144,7 +3151,7 @@ struct EmitVisitor
Emit("s");
break;
default:
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), CodePosition(), "unhandled HLSL register type");
break;
}
Emit(info.index);
@@ -3192,7 +3199,7 @@ struct EmitVisitor
if (!modifier) return nullptr;
auto computedLayout = modifier->layout;
- assert(computedLayout);
+ SLANG_RELEASE_ASSERT(computedLayout);
auto varLayout = computedLayout.As<VarLayout>();
return varLayout;
@@ -3208,18 +3215,18 @@ struct EmitVisitor
// We expect/require the data type to be a user-defined `struct` type
auto declRefType = dataType->As<DeclRefType>();
- assert(declRefType);
+ SLANG_RELEASE_ASSERT(declRefType);
// We expect to always have layout information
layout = maybeFetchLayout(varDecl, layout);
- assert(layout);
+ SLANG_RELEASE_ASSERT(layout);
// We expect the layout to be for a structured type...
RefPtr<ParameterBlockTypeLayout> bufferLayout = layout->typeLayout.As<ParameterBlockTypeLayout>();
- assert(bufferLayout);
+ SLANG_RELEASE_ASSERT(bufferLayout);
RefPtr<StructTypeLayout> structTypeLayout = bufferLayout->elementTypeLayout.As<StructTypeLayout>();
- assert(structTypeLayout);
+ SLANG_RELEASE_ASSERT(structTypeLayout);
if( auto constantBufferType = parameterBlockType->As<ConstantBufferType>() )
{
@@ -3239,7 +3246,7 @@ struct EmitVisitor
EmitSemantics(varDecl, kESemanticMask_None);
auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer);
- assert(info);
+ SLANG_RELEASE_ASSERT(info);
emitHLSLRegisterSemantic(*info);
Emit("\n{\n");
@@ -3254,7 +3261,7 @@ struct EmitVisitor
EmitVarDeclCommon(field);
RefPtr<VarLayout> fieldLayout = structTypeLayout->fields[fieldIndex];
- assert(fieldLayout->varDecl.GetName() == field.GetName());
+ SLANG_RELEASE_ASSERT(fieldLayout->varDecl.GetName() == field.GetName());
// Emit explicit layout annotations for every field
for( auto rr : fieldLayout->resourceInfos )
@@ -3273,7 +3280,7 @@ struct EmitVisitor
// If the member of the cbuffer uses a resource, it had better
// appear as part of the cubffer layout as well.
auto cbufferResource = layout->FindResourceInfo(kind);
- assert(cbufferResource);
+ SLANG_RELEASE_ASSERT(cbufferResource);
offsetResource.index += cbufferResource->index;
offsetResource.space += cbufferResource->space;
@@ -3372,7 +3379,7 @@ struct EmitVisitor
// We expect/require the data type to be a user-defined `struct` type
auto declRefType = dataType->As<DeclRefType>();
- assert(declRefType);
+ SLANG_RELEASE_ASSERT(declRefType);
// We expect the layout, if present, to be for a structured type...
RefPtr<StructTypeLayout> structTypeLayout;
@@ -3386,7 +3393,7 @@ struct EmitVisitor
}
structTypeLayout = typeLayout.As<StructTypeLayout>();
- assert(structTypeLayout);
+ SLANG_RELEASE_ASSERT(structTypeLayout);
emitGLSLLayoutQualifiers(layout);
}
@@ -3413,7 +3420,7 @@ struct EmitVisitor
}
else
{
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), varDecl, "unhandled GLSL shader parameter kind");
Emit("uniform");
}
@@ -3471,7 +3478,7 @@ struct EmitVisitor
break;
default:
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), varDecl, "unhandled code generation target");
break;
}
}
@@ -3696,7 +3703,7 @@ struct EmitVisitor
}
else
{
- throw "unimplemented";
+ SLANG_UNEXPECTED("unhandled declaration kind");
}
}
};
@@ -3746,13 +3753,13 @@ String emitEntryPoint(
auto elementTypeStructLayout = elementTypeLayout.As<StructTypeLayout>();
// We expect all constant buffers to contain `struct` types for now
- assert(elementTypeStructLayout);
+ SLANG_RELEASE_ASSERT(elementTypeStructLayout);
globalStructLayout = elementTypeStructLayout.Ptr();
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("uhandled global-scope binding layout");
}
sharedContext.globalStructLayout = globalStructLayout;
diff --git a/source/slang/lexer.cpp b/source/slang/lexer.cpp
index d8211fb20..49856c1c9 100644
--- a/source/slang/lexer.cpp
+++ b/source/slang/lexer.cpp
@@ -11,14 +11,14 @@ namespace Slang
Token* TokenList::begin() const
{
- assert(mTokens.Count());
+ SLANG_ASSERT(mTokens.Count());
return &mTokens[0];
}
Token* TokenList::end() const
{
- assert(mTokens.Count());
- assert(mTokens[mTokens.Count()-1].Type == TokenType::EndOfFile);
+ SLANG_ASSERT(mTokens.Count());
+ SLANG_ASSERT(mTokens[mTokens.Count()-1].Type == TokenType::EndOfFile);
return &mTokens[mTokens.Count() - 1];
}
@@ -48,7 +48,7 @@ namespace Slang
{
if (mCursor == mEnd)
return TokenType::EndOfFile;
- assert(mCursor);
+ SLANG_ASSERT(mCursor);
return mCursor->Type;
}
@@ -56,7 +56,7 @@ namespace Slang
{
if (!mCursor)
return CodePosition();
- assert(mCursor);
+ SLANG_ASSERT(mCursor);
return mCursor->Position;
}
@@ -135,7 +135,7 @@ namespace Slang
//
static void handleNewLineInner(Lexer* lexer, int c)
{
- assert(c == '\n' || c == '\r');
+ SLANG_ASSERT(c == '\n' || c == '\r');
int d = peekRaw(lexer);
if( (c ^ d) == ('\n' ^ '\r') )
@@ -774,26 +774,26 @@ namespace Slang
String getStringLiteralTokenValue(Token const& token)
{
- assert(token.Type == TokenType::StringLiteral
+ SLANG_ASSERT(token.Type == TokenType::StringLiteral
|| token.Type == TokenType::CharLiteral);
char const* cursor = token.Content.begin();
char const* end = token.Content.end();
auto quote = *cursor++;
- assert(quote == '\'' || quote == '"');
+ SLANG_ASSERT(quote == '\'' || quote == '"');
StringBuilder valueBuilder;
for(;;)
{
- assert(cursor != end);
+ SLANG_ASSERT(cursor != end);
auto c = *cursor++;
// If we see a closing quote, then we are at the end of the string literal
if(c == quote)
{
- assert(cursor == end);
+ SLANG_ASSERT(cursor == end);
return valueBuilder.ProduceString();
}
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index c61003bc6..52b865ba3 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -186,7 +186,7 @@ class TupleVarDecl : public VarDeclBase
public:
virtual void accept(IDeclVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
TupleTypeModifier* tupleType;
@@ -201,7 +201,7 @@ class TupleExpr : public ExpressionSyntaxNode
public:
virtual void accept(IExprVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
struct Element
@@ -225,7 +225,7 @@ class VaryingTupleVarDecl : public VarDeclBase
public:
virtual void accept(IDeclVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
};
@@ -236,7 +236,7 @@ class VaryingTupleExpr : public ExpressionSyntaxNode
public:
virtual void accept(IExprVisitor *, void *) override
{
- throw "unexpected";
+ SLANG_UNEXPECTED("tuples should not appear in lowered code");
}
struct Element
@@ -667,10 +667,10 @@ struct LoweringVisitor
for (auto dd : decl->tupleDecls)
{
auto tupleVarMod = dd->FindModifier<TupleVarModifier>();
- assert(tupleVarMod);
+ SLANG_RELEASE_ASSERT(tupleVarMod);
auto tupleFieldMod = tupleVarMod->tupleField;
- assert(tupleFieldMod);
- assert(tupleFieldMod->decl);
+ SLANG_RELEASE_ASSERT(tupleFieldMod);
+ SLANG_RELEASE_ASSERT(tupleFieldMod->decl);
TupleExpr::Element elem;
elem.tupleFieldDeclRef = makeDeclRef(tupleFieldMod->decl);
@@ -799,7 +799,7 @@ struct LoweringVisitor
if (leftTuple->primaryExpr)
{
- assert(rightTuple->primaryExpr);
+ SLANG_RELEASE_ASSERT(rightTuple->primaryExpr);
resultTuple->primaryExpr = createAssignExpr(
leftTuple->primaryExpr,
@@ -807,7 +807,7 @@ struct LoweringVisitor
}
auto elementCount = leftTuple->tupleElements.Count();
- assert(elementCount == rightTuple->tupleElements.Count());
+ SLANG_RELEASE_ASSERT(elementCount == rightTuple->tupleElements.Count());
for (UInt ee = 0; ee < elementCount; ++ee)
{
auto leftElement = leftTuple->tupleElements[ee];
@@ -827,7 +827,7 @@ struct LoweringVisitor
}
else
{
- assert(!leftTuple && !rightTuple);
+ SLANG_RELEASE_ASSERT(!leftTuple && !rightTuple);
}
auto leftVaryingTuple = leftExpr.As<VaryingTupleExpr>();
@@ -838,10 +838,10 @@ struct LoweringVisitor
resultTuple->Type.type = lowerType(leftExpr->Type.type);
resultTuple->Position = leftExpr->Position;
- assert(resultTuple->Type.type);
+ SLANG_RELEASE_ASSERT(resultTuple->Type.type);
UInt elementCount = leftVaryingTuple->elements.Count();
- assert(elementCount == rightVaryingTuple->elements.Count());
+ SLANG_RELEASE_ASSERT(elementCount == rightVaryingTuple->elements.Count());
for (UInt ee = 0; ee < elementCount; ++ee)
{
@@ -1027,7 +1027,7 @@ struct LoweringVisitor
auto loweredExpr = new VaryingTupleExpr();
loweredExpr->Type.type = getSubscripResultType(baseExpr->Type.type);
- assert(loweredExpr->Type.type);
+ SLANG_RELEASE_ASSERT(loweredExpr->Type.type);
for (auto elem : baseVaryingTuple->elements)
{
@@ -1100,7 +1100,7 @@ struct LoweringVisitor
RefPtr<AggTypeCtorExpr> resultExpr = new AggTypeCtorExpr();
resultExpr->Type = varyingTupleExpr->Type;
resultExpr->base.type = varyingTupleExpr->Type.type;
- assert(resultExpr->Type.type);
+ SLANG_RELEASE_ASSERT(resultExpr->Type.type);
for (auto elem : varyingTupleExpr->elements)
{
@@ -1214,6 +1214,11 @@ struct LoweringVisitor
return loweredExpr;
}
+ DiagnosticSink* getSink()
+ {
+ return &shared->compileRequest->mSink;
+ }
+
RefPtr<ExpressionSyntaxNode> visitMemberExpressionSyntaxNode(
MemberExpressionSyntaxNode* expr)
{
@@ -1244,8 +1249,8 @@ struct LoweringVisitor
return tupleFieldExpr;
auto tupleFieldTupleExpr = tupleFieldExpr.As<TupleExpr>();
- assert(tupleFieldTupleExpr);
- assert(!tupleFieldTupleExpr->primaryExpr);
+ SLANG_RELEASE_ASSERT(tupleFieldTupleExpr);
+ SLANG_RELEASE_ASSERT(!tupleFieldTupleExpr->primaryExpr);
RefPtr<MemberExpressionSyntaxNode> loweredPrimaryExpr = new MemberExpressionSyntaxNode();
@@ -1274,11 +1279,11 @@ struct LoweringVisitor
}
}
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "failed to find tuple field during lowering");
}
// Default handling:
- assert(!dynamic_cast<TupleVarDecl*>(loweredDeclRef.getDecl()));
+ SLANG_RELEASE_ASSERT(!dynamic_cast<TupleVarDecl*>(loweredDeclRef.getDecl()));
RefPtr<MemberExpressionSyntaxNode> loweredExpr = new MemberExpressionSyntaxNode();
lowerExprCommon(loweredExpr, expr);
@@ -1344,7 +1349,7 @@ struct LoweringVisitor
return state->loweredStmt;
}
- assert(!"unexepcted");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), originalStmt, "failed to find outer statement during lowering");
return nullptr;
}
@@ -1755,7 +1760,7 @@ struct LoweringVisitor
if (auto litVal = dynamic_cast<ConstantIntVal*>(val))
return val;
- throw 99;
+ SLANG_UNEXPECTED("unhandled value kind");
}
RefPtr<Substitutions> translateSubstitutions(
@@ -1871,7 +1876,7 @@ struct LoweringVisitor
// translated, which the user will maintain via pua/pop.
//
- assert(parentDecl);
+ SLANG_RELEASE_ASSERT(parentDecl);
addMember(parentDecl, decl);
}
@@ -2337,7 +2342,7 @@ struct LoweringVisitor
continue;
// TODO: need to extract the initializer for this field
- assert(!info.initExpr);
+ SLANG_RELEASE_ASSERT(!info.initExpr);
RefPtr<ExpressionSyntaxNode> fieldInitExpr;
String fieldName = info.name + "_" + dd.GetName();
@@ -2346,7 +2351,7 @@ struct LoweringVisitor
Decl* originalFieldDecl;
shared->mapLoweredDeclToOriginal.TryGetValue(dd, originalFieldDecl);
- assert(originalFieldDecl);
+ SLANG_RELEASE_ASSERT(originalFieldDecl);
RefPtr<VarLayout> fieldLayout;
if(info.tupleTypeLayout)
@@ -2477,7 +2482,7 @@ struct LoweringVisitor
RefPtr<StructTypeLayout> tupleTypeLayout)
{
// Not handling initializers just yet...
- assert(!initExpr);
+ SLANG_RELEASE_ASSERT(!initExpr);
// We'll need a placeholder declaration to wrap the whole thing up:
RefPtr<TupleVarDecl> tupleDecl = new TupleVarDecl();
@@ -2745,7 +2750,7 @@ struct LoweringVisitor
// declarations.
// We can't easily support `in out` declarations with this approach
- assert(!(inRes && outRes));
+ SLANG_RELEASE_ASSERT(!(inRes && outRes));
RefPtr<ExpressionSyntaxNode> loweredExpr;
if (inRes)
@@ -2764,7 +2769,7 @@ struct LoweringVisitor
VaryingParameterDirection::Output);
}
- assert(loweredExpr);
+ SLANG_RELEASE_ASSERT(loweredExpr);
auto loweredDecl = createVaryingTupleVarDecl(
decl,
loweredExpr);
@@ -2987,7 +2992,7 @@ struct LoweringVisitor
RefPtr<ExpressionSyntaxNode> globalVarExpr;
// Handle system-value inputs/outputs
- assert(varLayout);
+ SLANG_RELEASE_ASSERT(varLayout);
auto systemValueSemantic = varLayout->systemValueSemantic;
if (systemValueSemantic.Length() != 0)
{
@@ -3124,7 +3129,7 @@ struct LoweringVisitor
}
else
{
- assert(!"unhandled");
+ getSink()->diagnose(info.varChain->varDecl, Diagnostics::unknownSystemValueSemantic, systemValueSemantic);
}
}
@@ -3202,7 +3207,7 @@ struct LoweringVisitor
RefPtr<ExpressionType> varType,
RefPtr<VarLayout> varLayout)
{
- assert(varLayout);
+ SLANG_RELEASE_ASSERT(varLayout);
if (auto basicType = varType->As<BasicExpressionType>())
{
@@ -3252,7 +3257,7 @@ struct LoweringVisitor
RefPtr<VaryingTupleExpr> tupleExpr = new VaryingTupleExpr();
tupleExpr->Type.type = varType;
- assert(tupleExpr->Type.type);
+ SLANG_RELEASE_ASSERT(tupleExpr->Type.type);
for (auto fieldDeclRef : getMembersOfType<VarDeclBase>(aggTypeDeclRef))
{
@@ -3271,14 +3276,14 @@ struct LoweringVisitor
// Need to find the layout for the given field...
Decl* originalFieldDecl = nullptr;
shared->mapLoweredDeclToOriginal.TryGetValue(fieldDeclRef.getDecl(), originalFieldDecl);
- assert(originalFieldDecl);
+ SLANG_RELEASE_ASSERT(originalFieldDecl);
auto structTypeLayout = varLayout->typeLayout.As<StructTypeLayout>();
- assert(structTypeLayout);
+ SLANG_RELEASE_EXPECT(structTypeLayout, "expected a structure type layout");
RefPtr<VarLayout> fieldLayout;
structTypeLayout->mapVarToLayout.TryGetValue(originalFieldDecl, fieldLayout);
- assert(fieldLayout);
+ SLANG_RELEASE_ASSERT(fieldLayout);
auto loweredFieldExpr = lowerShaderParameterToGLSLGLobalsRec(
fieldInfo,
@@ -3414,7 +3419,7 @@ struct LoweringVisitor
{
RefPtr<VarLayout> paramLayout;
entryPointLayout->mapVarToLayout.TryGetValue(paramDecl.Ptr(), paramLayout);
- assert(paramLayout);
+ SLANG_RELEASE_ASSERT(paramLayout);
RefPtr<Variable> localVarDecl = new Variable();
localVarDecl->Position = paramDecl->Position;
@@ -3657,13 +3662,13 @@ static RefPtr<StructTypeLayout> getGlobalStructLayout(
auto elementTypeStructLayout = elementTypeLayout.As<StructTypeLayout>();
// We expect all constant buffers to contain `struct` types for now
- assert(elementTypeStructLayout);
+ SLANG_RELEASE_ASSERT(elementTypeStructLayout);
globalStructLayout = elementTypeStructLayout.Ptr();
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled type for global-scope parameter layout");
}
return globalStructLayout;
}
diff --git a/source/slang/options.cpp b/source/slang/options.cpp
index bb292a4dc..d5f0f2f3c 100644
--- a/source/slang/options.cpp
+++ b/source/slang/options.cpp
@@ -81,7 +81,7 @@ struct OptionsParser
{
auto translationUnitIndex = spAddTranslationUnit(compileRequest, language, nullptr);
- assert(UInt(translationUnitIndex) == rawTranslationUnits.Count());
+ SLANG_RELEASE_ASSERT(UInt(translationUnitIndex) == rawTranslationUnits.Count());
RawTranslationUnit rawTranslationUnit;
rawTranslationUnit.sourceLanguage = language;
diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp
index a8e71b22a..17c2bb193 100644
--- a/source/slang/parameter-binding.cpp
+++ b/source/slang/parameter-binding.cpp
@@ -7,8 +7,6 @@
#include "../../slang.h"
-#define SLANG_EXHAUSTIVE_SWITCH() default: assert(!"unexpected"); break;
-
namespace Slang {
struct ParameterInfo;
@@ -34,8 +32,8 @@ bool operator<(UsedRange left, UsedRange right)
static bool rangesOverlap(UsedRange const& x, UsedRange const& y)
{
- assert(x.begin <= x.end);
- assert(y.begin <= y.end);
+ SLANG_ASSERT(x.begin <= x.end);
+ SLANG_ASSERT(y.begin <= y.end);
// If they don't overlap, then one must be earlier than the other,
// and that one must therefore *end* before the other *begins*
@@ -503,14 +501,14 @@ getTypeLayoutForGlobalShaderParameter_GLSL(
if (auto effectiveVaryingInputType = tryGetEffectiveTypeForGLSLVaryingInput(context, varDecl))
{
// We expect to handle these elsewhere
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(context), varDecl, "GLSL varying input");
return CreateTypeLayout(effectiveVaryingInputType, rules->getVaryingInputRules());
}
if (auto effectiveVaryingOutputType = tryGetEffectiveTypeForGLSLVaryingOutput(context, varDecl))
{
// We expect to handle these elsewhere
- assert(!"unexpected");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(context), varDecl, "GLSL varying output");
return CreateTypeLayout(effectiveVaryingOutputType, rules->getVaryingOutputRules());
}
@@ -568,7 +566,7 @@ getTypeLayoutForGlobalShaderParameter(
return getTypeLayoutForGlobalShaderParameter_GLSL(context, varDecl);
default:
- assert(false);
+ SLANG_UNEXPECTED("unhandled source language");
return nullptr;
}
}
@@ -900,7 +898,7 @@ void generateParameterBindings(
RefPtr<ParameterInfo> parameterInfo)
{
// There must be at least one declaration for the parameter.
- assert(parameterInfo->varLayouts.Count() != 0);
+ SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.Count() != 0);
// Iterate over all declarations looking for explicit binding information.
for( auto& varLayout : parameterInfo->varLayouts )
@@ -928,7 +926,7 @@ static void completeBindingsForParameter(
// that earlier code has validated that the declarations
// "match".
- assert(parameterInfo->varLayouts.Count() != 0);
+ SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.Count() != 0);
auto firstVarLayout = parameterInfo->varLayouts.First();
auto firstTypeLayout = firstVarLayout->typeLayout;
@@ -1258,7 +1256,7 @@ static RefPtr<TypeLayout> processEntryPointParameter(
for (auto rr : fieldTypeLayout->resourceInfos)
{
- assert(rr.count != 0);
+ SLANG_RELEASE_ASSERT(rr.count != 0);
auto structRes = structLayout->findOrAddResourceInfo(rr.kind);
fieldVarLayout->findOrAddResourceInfo(rr.kind)->index = structRes->count;
@@ -1273,7 +1271,7 @@ static RefPtr<TypeLayout> processEntryPointParameter(
}
else
{
- assert(!"unimplemented");
+ SLANG_UNEXPECTED("unhandled type kind");
}
}
// If we ran into an error in checking the user's code, then skip this parameter
@@ -1281,12 +1279,8 @@ static RefPtr<TypeLayout> processEntryPointParameter(
{
return nullptr;
}
- else
- {
- assert(!"unimplemented");
- }
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled type kind");
return nullptr;
}
@@ -1545,7 +1539,7 @@ void generateParameterBindings(
bool anyGlobalUniforms = false;
for( auto& parameterInfo : sharedContext.parameters )
{
- assert(parameterInfo->varLayouts.Count() != 0);
+ SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.Count() != 0);
auto firstVarLayout = parameterInfo->varLayouts.First();
// Does the field have any uniform data?
@@ -1606,7 +1600,7 @@ void generateParameterBindings(
UniformLayoutInfo structLayoutInfo = globalScopeRules->BeginStructLayout();
for( auto& parameterInfo : sharedContext.parameters )
{
- assert(parameterInfo->varLayouts.Count() != 0);
+ SLANG_RELEASE_ASSERT(parameterInfo->varLayouts.Count() != 0);
auto firstVarLayout = parameterInfo->varLayouts.First();
// Does the field have any uniform data?
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index a624c58c5..801628e30 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -848,8 +848,9 @@ namespace Slang
}
else
{
+ SLANG_DIAGNOSE_UNEXPECTED(parser->sink, parser->tokenReader.PeekLoc(), "needed a modifier");
+
parser->ReadToken(TokenType::Identifier);
- assert(!"unexpected");
}
}
}
@@ -1377,7 +1378,7 @@ namespace Slang
void addDecl(
RefPtr<Decl> newDecl)
{
- assert(newDecl);
+ SLANG_ASSERT(newDecl);
if( decl )
{
@@ -1715,7 +1716,7 @@ namespace Slang
RefPtr<Modifier> result;
RefPtr<Modifier>* link = &result;
- assert(!*link);
+ SLANG_ASSERT(!*link);
for (;;)
{
@@ -2440,7 +2441,7 @@ namespace Slang
ParseDeclBody(this, program, TokenType::EndOfFile);
PopScope();
- assert(currentScope == outerScope);
+ SLANG_RELEASE_ASSERT(currentScope == outerScope);
currentScope = nullptr;
}
diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp
index a4cccf4f4..ec38a7214 100644
--- a/source/slang/preprocessor.cpp
+++ b/source/slang/preprocessor.cpp
@@ -705,8 +705,7 @@ static void MaybeBeginMacroExpansion(
UInt argCount = argIndex;
if (argCount != paramCount)
{
- // TODO: diagnose
- throw 99;
+ GetSink(preprocessor)->diagnose(PeekLoc(preprocessor), Diagnostics::wrongNumberOfArgumentsToMacro, paramCount, argCount);
}
// We are ready to expand.
@@ -1006,7 +1005,7 @@ static void beginConditional(
bool enable)
{
Preprocessor* preprocessor = context->preprocessor;
- assert(inputStream);
+ SLANG_ASSERT(inputStream);
PreprocessorConditional* conditional = CreateConditional(preprocessor);
@@ -1346,7 +1345,7 @@ static void HandleIfNDefDirective(PreprocessorDirectiveContext* context)
static void HandleElseDirective(PreprocessorDirectiveContext* context)
{
PreprocessorInputStream* inputStream = context->preprocessor->inputStream;
- assert(inputStream);
+ SLANG_ASSERT(inputStream);
// if we aren't inside a conditional, then error
PreprocessorConditional* conditional = inputStream->conditional;
@@ -1386,7 +1385,7 @@ static void HandleElifDirective(PreprocessorDirectiveContext* context)
// Need to grab current input stream *before* we try to parse
// the conditional expression.
PreprocessorInputStream* inputStream = context->preprocessor->inputStream;
- assert(inputStream);
+ SLANG_ASSERT(inputStream);
// HACK(tfoley): handle an empty `elif` like an `else` directive
//
@@ -1438,7 +1437,7 @@ static void HandleElifDirective(PreprocessorDirectiveContext* context)
static void HandleEndIfDirective(PreprocessorDirectiveContext* context)
{
PreprocessorInputStream* inputStream = context->preprocessor->inputStream;
- assert(inputStream);
+ SLANG_ASSERT(inputStream);
// if we aren't inside a conditional, then error
PreprocessorConditional* conditional = inputStream->conditional;
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index 18fa3362d..18cf58a92 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -6,6 +6,12 @@
#include <assert.h>
+// Don't signal errors for stuff we don't implement here,
+// and instead just try to return things defensively
+//
+// Slang developers can switch this when debugging.
+#define SLANG_REFLECTION_UNEXPECTED() do {} while(0)
+
// Implementation to back public-facing reflection API
using namespace Slang;
@@ -150,7 +156,7 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType)
return SLANG_TYPE_KIND_NONE;
}
- assert(!"unexpected");
+ SLANG_REFLECTION_UNEXPECTED();
return SLANG_TYPE_KIND_NONE;
}
@@ -308,7 +314,7 @@ SLANG_API SlangScalarType spReflectionType_GetScalarType(SlangReflectionType* in
#undef CASE
default:
- assert(!"unexpected");
+ SLANG_REFLECTION_UNEXPECTED();
return SLANG_SCALAR_TYPE_NONE;
break;
}
@@ -967,7 +973,7 @@ static void emitReflectionVarBindingInfoJSON(
default:
write(writer, "unknown");
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled case");
break;
}
write(writer, "\"");
@@ -1071,7 +1077,7 @@ static void emitReflectionScalarTypeInfoJSON(
{
default:
write(writer, "unknown");
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled case");
break;
#define CASE(TAG, ID) case slang::TypeReflection::ScalarType::TAG: write(writer, #ID); break
CASE(Void, void);
@@ -1109,7 +1115,7 @@ static void emitReflectionTypeInfoJSON(
{
default:
write(writer, "unknown");
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled case");
break;
#define CASE(SHAPE, NAME) case SLANG_##SHAPE: write(writer, #NAME); break
@@ -1141,7 +1147,7 @@ static void emitReflectionTypeInfoJSON(
{
default:
write(writer, "unknown");
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled case");
break;
case SLANG_RESOURCE_ACCESS_READ:
@@ -1253,7 +1259,7 @@ static void emitReflectionTypeInfoJSON(
break;
default:
- assert(!"unimplemented");
+ SLANG_UNEXPECTED("unhandled case");
break;
}
}
@@ -1374,58 +1380,6 @@ static void emitReflectionVarInfoJSON(
emitReflectionTypeJSON(writer, var->getType());
}
-#if 0
-static void emitReflectionBindingInfoJSON(
- PrettyWriter& writer,
-
- ReflectionParameterNode* param)
-{
- auto info = &param->binding;
-
- if( info->category == SLANG_PARAMETER_CATEGORY_MIXED )
- {
- write(writer,"\"bindings\": [\n");
- indent(writer);
-
- ReflectionSize bindingCount = info->bindingCount;
- assert(bindingCount);
- ReflectionParameterBindingInfo* bindings = info->bindings;
- for( ReflectionSize bb = 0; bb < bindingCount; ++bb )
- {
- if (bb != 0) write(writer, ",\n");
-
- write(writer,"{");
- auto& binding = bindings[bb];
- emitReflectionVarBindingInfoJSON(
- writer,
- binding.category,
- binding.index,
- (ReflectionSize) param->GetTypeLayout()->GetSize(binding.category),
- binding.space);
-
- write(writer,"}");
- }
- dedent(writer);
- write(writer,"\n]");
- }
- else
- {
- write(writer,"\"binding\": {");
- indent(writer);
-
- emitReflectionVarBindingInfoJSON(
- writer,
- info->category,
- info->index,
- (ReflectionSize) param->GetTypeLayout()->GetSize(info->category),
- info->space);
-
- dedent(writer);
- write(writer,"}");
- }
-}
-#endif
-
static void emitReflectionParamJSON(
PrettyWriter& writer,
slang::VariableLayoutReflection* param)
diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp
index 7850b0ce0..60b69818c 100644
--- a/source/slang/slang-stdlib.cpp
+++ b/source/slang/slang-stdlib.cpp
@@ -1289,7 +1289,7 @@ namespace Slang
for(int M = 2; M <= (N-2); ++M)
{
int K = N - M;
- assert(K >= 2);
+ SLANG_ASSERT(K >= 2);
sb << "__init(vector<T," << M << "> " << kVectorNames[M];
sb << ", vector<T," << K << "> ";
@@ -1453,7 +1453,7 @@ namespace Slang
break;
default:
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled resource shape");
break;
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 89db62ec8..caa50ad0e 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -571,7 +571,7 @@ void Session::addBuiltinSource(
OutputDebugStringA(compileRequest->mDiagnosticOutput.Buffer());
#endif
- assert(!"error in stdlib");
+ SLANG_UNEXPECTED("error in Slang standard library");
}
// Extract the AST for the code we just parsed
@@ -831,8 +831,16 @@ SLANG_API int spCompile(
{
auto req = REQ(request);
- int anyErrors = req->executeActions();
- return anyErrors;
+ try
+ {
+ int anyErrors = req->executeActions();
+ return anyErrors;
+ }
+ catch (...)
+ {
+ req->mSink.diagnose(Slang::CodePosition(), Slang::Diagnostics::compilationAborted);
+ return 1;
+ }
}
SLANG_API int
diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h
index 11ec30e62..03d4b749a 100644
--- a/source/slang/syntax-base-defs.h
+++ b/source/slang/syntax-base-defs.h
@@ -238,7 +238,7 @@ ABSTRACT_SYNTAX_CLASS(Decl, DeclBase)
bool IsChecked(DeclCheckState state) { return checkState >= state; }
void SetCheckState(DeclCheckState state)
{
- assert(state >= checkState);
+ SLANG_RELEASE_ASSERT(state >= checkState);
checkState = state;
}
)
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index 503fbbb0e..f3c940038 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -147,7 +147,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
{
// TODO(tfoley): worry about thread safety here?
et->canonicalType = et->CreateCanonicalType();
- assert(et->canonicalType);
+ SLANG_ASSERT(et->canonicalType);
}
return et->canonicalType;
}
@@ -314,14 +314,14 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
static RefPtr<ExpressionType> ExtractGenericArgType(RefPtr<Val> val)
{
auto type = val.As<ExpressionType>();
- assert(type.Ptr());
+ SLANG_RELEASE_ASSERT(type.Ptr());
return type;
}
static RefPtr<IntVal> ExtractGenericArgInteger(RefPtr<Val> val)
{
auto intVal = val.As<IntVal>();
- assert(intVal.Ptr());
+ SLANG_RELEASE_ASSERT(intVal.Ptr());
return intVal;
}
@@ -348,7 +348,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
}
else if (magicMod->name == "Vector")
{
- assert(subst && subst->args.Count() == 2);
+ SLANG_ASSERT(subst && subst->args.Count() == 2);
auto vecType = new VectorExpressionType();
vecType->declRef = declRef;
vecType->elementType = ExtractGenericArgType(subst->args[0]);
@@ -357,14 +357,14 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
}
else if (magicMod->name == "Matrix")
{
- assert(subst && subst->args.Count() == 3);
+ SLANG_ASSERT(subst && subst->args.Count() == 3);
auto matType = new MatrixExpressionType();
matType->declRef = declRef;
return matType;
}
else if (magicMod->name == "Texture")
{
- assert(subst && subst->args.Count() >= 1);
+ SLANG_ASSERT(subst && subst->args.Count() >= 1);
auto textureType = new TextureType(
TextureType::Flavor(magicMod->tag),
ExtractGenericArgType(subst->args[0]));
@@ -373,7 +373,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
}
else if (magicMod->name == "TextureSampler")
{
- assert(subst && subst->args.Count() >= 1);
+ SLANG_ASSERT(subst && subst->args.Count() >= 1);
auto textureType = new TextureSamplerType(
TextureType::Flavor(magicMod->tag),
ExtractGenericArgType(subst->args[0]));
@@ -382,7 +382,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
}
else if (magicMod->name == "GLSLImageType")
{
- assert(subst && subst->args.Count() >= 1);
+ SLANG_ASSERT(subst && subst->args.Count() >= 1);
auto textureType = new GLSLImageType(
TextureType::Flavor(magicMod->tag),
ExtractGenericArgType(subst->args[0]));
@@ -408,7 +408,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
#define CASE(n,T) \
else if(magicMod->name == #n) { \
- assert(subst && subst->args.Count() == 1); \
+ SLANG_ASSERT(subst && subst->args.Count() == 1); \
auto type = new T(); \
type->elementType = ExtractGenericArgType(subst->args[0]); \
type->declRef = declRef; \
@@ -450,7 +450,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
else
{
- throw "unimplemented";
+ SLANG_UNEXPECTED("unhandled type");
}
}
else
@@ -537,7 +537,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
bool NamedExpressionType::EqualsImpl(ExpressionType * /*type*/)
{
- assert(!"unreachable");
+ SLANG_UNEXPECTED("unreachable");
return false;
}
@@ -548,7 +548,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
int NamedExpressionType::GetHashCode()
{
- assert(!"unreachable");
+ SLANG_UNEXPECTED("unreachable");
return 0;
}
@@ -609,7 +609,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
int TypeType::GetHashCode()
{
- assert(!"unreachable");
+ SLANG_UNEXPECTED("unreachable");
return 0;
}
@@ -778,7 +778,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
return false;
UInt argCount = args.Count();
- assert(args.Count() == subst->args.Count());
+ SLANG_RELEASE_ASSERT(args.Count() == subst->args.Count());
for (UInt aa = 0; aa < argCount; ++aa)
{
if (!args[aa]->EqualsVal(subst->args[aa].Ptr()))
@@ -821,7 +821,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
if (!substitutions)
return expr;
- assert(!"unimplemented");
+ SLANG_UNIMPLEMENTED_X("generic substitution into expressions");
return expr;
}
@@ -928,7 +928,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
{
return constantVal->value;
}
- assert(!"unexpected");
+ SLANG_UNEXPECTED("needed a known integer value");
return 0;
}
@@ -1032,7 +1032,7 @@ void ExpressionType::accept(IValVisitor* visitor, void* extra)
#undef CASE
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled syntax class name");
return nullptr;
}
}
diff --git a/source/slang/token.cpp b/source/slang/token.cpp
index ff2ded818..69baf5e70 100644
--- a/source/slang/token.cpp
+++ b/source/slang/token.cpp
@@ -10,7 +10,7 @@ char const* TokenTypeToString(TokenType type)
switch( type )
{
default:
- assert(!"unexpected");
+ SLANG_ASSERT(!"unexpected");
return "<uknown>";
#define TOKEN(NAME, DESC) case TokenType::NAME: return DESC;
diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp
index b4bf8949f..245993881 100644
--- a/source/slang/type-layout.cpp
+++ b/source/slang/type-layout.cpp
@@ -38,8 +38,11 @@ struct DefaultLayoutRulesImpl : SimpleLayoutRulesImpl
case BaseType::Bool:
return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4, 4 );
+ case BaseType::Double:
+ return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8, 8 );
+
default:
- assert(!"unimplemented");
+ SLANG_UNEXPECTED("uhandled scalar type");
return SimpleLayoutInfo( LayoutResourceKind::Uniform, 0, 1 );
}
}
@@ -64,7 +67,7 @@ struct DefaultLayoutRulesImpl : SimpleLayoutRulesImpl
case slang::TypeReflection::ScalarType::Float64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8);
default:
- assert(!"unimplemented");
+ SLANG_UNEXPECTED("unhandled scalar type");
return SimpleLayoutInfo();
}
}
@@ -164,7 +167,7 @@ struct GLSLConstantBufferLayoutRulesImpl : DefaultConstantBufferLayoutRulesImpl
static SimpleLayoutInfo getGLSLVectorLayout(
SimpleLayoutInfo elementInfo, size_t elementCount)
{
- assert(elementInfo.kind == LayoutResourceKind::Uniform);
+ SLANG_RELEASE_ASSERT(elementInfo.kind == LayoutResourceKind::Uniform);
auto size = elementInfo.size * elementCount;
SimpleLayoutInfo vectorInfo(
LayoutResourceKind::Uniform,
@@ -380,7 +383,7 @@ struct HLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl
case ShaderParameterKind::InputRenderTarget:
// TODO: how to handle these?
default:
- assert(!"unimplemented");
+ SLANG_UNEXPECTED("unhandled shader parameter kind");
return SimpleLayoutInfo();
}
}
@@ -601,7 +604,7 @@ static int GetElementCount(RefPtr<IntVal> val)
// TODO(tfoley): do something sensible in this case
return 0;
}
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled integer literal kind");
return 0;
}
@@ -670,7 +673,7 @@ static SimpleLayoutInfo getParameterBlockLayoutInfo(
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("unhandled parameter block type");
return SimpleLayoutInfo();
}
}
@@ -696,8 +699,8 @@ createParameterBlockTypeLayout(
// and hence no uniform data).
//
typeLayout->uniformAlignment = parameterBlockInfo.alignment;
- assert(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
- assert(typeLayout->uniformAlignment == 1);
+ SLANG_RELEASE_ASSERT(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
+ SLANG_RELEASE_ASSERT(typeLayout->uniformAlignment == 1);
// TODO(tfoley): There is a subtle question here of whether
// a constant buffer declaration that then contains zero
@@ -801,7 +804,7 @@ LayoutRulesImpl* getParameterBufferElementTypeLayoutRules(
}
else
{
- assert(!"unexpected");
+ SLANG_UNEXPECTED("uhandled parameter block type");
return nullptr;
}
}
@@ -843,8 +846,8 @@ createStructuredBufferTypeLayout(
typeLayout->elementTypeLayout = elementTypeLayout;
typeLayout->uniformAlignment = info.alignment;
- assert(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
- assert(typeLayout->uniformAlignment == 1);
+ SLANG_RELEASE_ASSERT(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
+ SLANG_RELEASE_ASSERT(typeLayout->uniformAlignment == 1);
if( info.size != 0 )
{
@@ -1211,7 +1214,7 @@ SimpleLayoutInfo GetLayoutImpl(
continue;
// We should not have already processed this resource type
- assert(!fieldLayout->FindResourceInfo(fieldTypeResourceInfo.kind));
+ SLANG_RELEASE_ASSERT(!fieldLayout->FindResourceInfo(fieldTypeResourceInfo.kind));
// The field will need offset information for this kind
auto fieldResourceInfo = fieldLayout->AddResourceInfo(fieldTypeResourceInfo.kind);
@@ -1258,7 +1261,7 @@ SimpleLayoutInfo GetLayoutImpl(
}
// catch-all case in case nothing matched
- assert(!"unimplemented");
+ SLANG_ASSERT(!"unimplemented");
SimpleLayoutInfo info;
return GetSimpleLayoutImpl(
info,