diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-19 09:36:35 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-19 18:15:37 -0700 |
| commit | 3f48e1c0d84bf4909954154ad147559656e87516 (patch) | |
| tree | 0b93a109d51e6565560ad785519a863386490e2a | |
| parent | a2b8b4c20632d79721052abd232fe2d1bdf2700d (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.h | 29 | ||||
| -rw-r--r-- | source/core/exception.h | 16 | ||||
| -rw-r--r-- | source/core/slang-string.cpp | 8 | ||||
| -rw-r--r-- | source/core/slang-string.h | 4 | ||||
| -rw-r--r-- | source/core/smart-pointer.h | 5 | ||||
| -rw-r--r-- | source/slang/check.cpp | 217 | ||||
| -rw-r--r-- | source/slang/compiler.cpp | 63 | ||||
| -rw-r--r-- | source/slang/diagnostic-defs.h | 10 | ||||
| -rw-r--r-- | source/slang/diagnostics.cpp | 2 | ||||
| -rw-r--r-- | source/slang/diagnostics.h | 6 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 123 | ||||
| -rw-r--r-- | source/slang/lexer.cpp | 20 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 77 | ||||
| -rw-r--r-- | source/slang/options.cpp | 2 | ||||
| -rw-r--r-- | source/slang/parameter-binding.cpp | 30 | ||||
| -rw-r--r-- | source/slang/parser.cpp | 9 | ||||
| -rw-r--r-- | source/slang/preprocessor.cpp | 11 | ||||
| -rw-r--r-- | source/slang/reflection.cpp | 72 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 14 | ||||
| -rw-r--r-- | source/slang/syntax-base-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 34 | ||||
| -rw-r--r-- | source/slang/token.cpp | 2 | ||||
| -rw-r--r-- | source/slang/type-layout.cpp | 29 |
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 = ¶m->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, |
