summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-19 09:36:35 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-19 18:15:37 -0700
commit3f48e1c0d84bf4909954154ad147559656e87516 (patch)
tree0b93a109d51e6565560ad785519a863386490e2a
parenta2b8b4c20632d79721052abd232fe2d1bdf2700d (diff)
Try to improve handling of failures during compilation
The change is mostly about trying to make sure the compiler "fails safe" when it encounters an internal assumption that isn't met. Most internal errors will now throw exceptions (yes, exceptions are evil, but this will work for now), and these get caught in `spCompile` so that they don't propagate to the user (they just see a message that compilation aborted due to an internal error). Subsequent changes are going to need to work on diagnosing as many of these situations as possible, so that users can at least know what construct in their code was unexpected or unhandled by the compiler.
-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,