summaryrefslogtreecommitdiffstats
path: root/source/slang/check.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-04-20 17:54:39 -0700
committerGitHub <noreply@github.com>2018-04-20 17:54:39 -0700
commit163d3068e332703cc499446fff37230a7c68e8f2 (patch)
treea1d0b9507ab01c908811603d8cde47736bdbe3ef /source/slang/check.cpp
parent2f782d403ae5729b6c93fbe92577ee01f7a8d608 (diff)
Better diagnostics when compilation is aborted (#517)
* Improve messages when compilation is aborted. Make sure to include the information from any `Slang::Exception` that was thrown, so that the poor user can at least point us at our own message string from an assertion failure. This doesn't provide them line-number information in their code or the Slang codebase, so there is still work to be done in making the compiler more friendly about this stuff. * When aborting compilation, try to note what source location we were working on This is handled by having exception handlers on the stack at key bottleneck points in semantic checking and IR generation, which can then emit a diagnostic to note what we were working on when things failed. This is not intended to be an indiciation to the user that their code is at fault for a compiler crash (it is always our fault), but might give them a chance to work around whatever bug is blocking them.
Diffstat (limited to 'source/slang/check.cpp')
-rw-r--r--source/slang/check.cpp53
1 files changed, 49 insertions, 4 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index acf473998..5fd8be2d5 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -455,6 +455,51 @@ namespace Slang
innerDeclRef);
}
+ // This routine is a bottleneck for all declaration checking,
+ // so that we can add some quality-of-life features for users
+ // in cases where the compiler crashes
+ void dispatchDecl(DeclBase* decl)
+ {
+ try
+ {
+ DeclVisitor::dispatch(decl);
+ }
+ // Don't emit any context message for an explicit `AbortCompilationException`
+ // because it should only happen when an error is already emitted.
+ catch(AbortCompilationException&) { throw; }
+ catch(...)
+ {
+ getCompileRequest()->noteInternalErrorLoc(decl->loc);
+ throw;
+ }
+ }
+ void dispatchStmt(Stmt* stmt)
+ {
+ try
+ {
+ StmtVisitor::dispatch(stmt);
+ }
+ catch(AbortCompilationException&) { throw; }
+ catch(...)
+ {
+ getCompileRequest()->noteInternalErrorLoc(stmt->loc);
+ throw;
+ }
+ }
+ void dispatchExpr(Expr* expr)
+ {
+ try
+ {
+ ExprVisitor::dispatch(expr);
+ }
+ catch(AbortCompilationException&) { throw; }
+ catch(...)
+ {
+ getCompileRequest()->noteInternalErrorLoc(expr->loc);
+ throw;
+ }
+ }
+
// Make sure a declaration has been checked, so we can refer to it.
// Note that this may lead to us recursively invoking checking,
// so this may not be the best way to handle things.
@@ -499,7 +544,7 @@ namespace Slang
}
// Use visitor pattern to dispatch to correct case
- DeclVisitor::dispatch(decl);
+ dispatchDecl(decl);
if(state > decl->checkState)
{
@@ -2492,7 +2537,7 @@ namespace Slang
{
for (auto decl : declGroup->decls)
{
- DeclVisitor::dispatch(decl);
+ dispatchDecl(decl);
}
}
@@ -2549,7 +2594,7 @@ namespace Slang
void checkStmt(Stmt* stmt)
{
if (!stmt) return;
- StmtVisitor::dispatch(stmt);
+ dispatchStmt(stmt);
checkModifiers(stmt);
}
@@ -3052,7 +3097,7 @@ namespace Slang
// 2. `EnsureDecl()` is specialized for `Decl*` instead of `DeclBase*`
// and trying to special case `DeclGroup*` here feels silly.
//
- DeclVisitor::dispatch(stmt->decl);
+ dispatchDecl(stmt->decl);
}
void visitBlockStmt(BlockStmt* stmt)