diff options
| author | Tim Foley <tim.foley.is@gmail.com> | 2017-07-19 18:52:38 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-19 18:52:38 -0700 |
| commit | f07c01ceb012b9b325a8ecebd12cdd5797d8d5b3 (patch) | |
| tree | 0b93a109d51e6565560ad785519a863386490e2a /source | |
| parent | a2b8b4c20632d79721052abd232fe2d1bdf2700d (diff) | |
| parent | 3f48e1c0d84bf4909954154ad147559656e87516 (diff) | |
Merge pull request #128 from tfoleyNV/improve-failure-modes
Try to improve handling of failures during compilation
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/common.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, |
