diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/check.cpp | 29 | ||||
| -rw-r--r-- | source/slang/diagnostic-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 6 |
3 files changed, 36 insertions, 2 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index e2d519a4c..ea7f1be2a 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -481,7 +481,33 @@ namespace Slang if (decl->checkState == DeclCheckState::CheckingHeader) { // We tried to reference the same declaration while checking it! + // + // TODO: we should ideally be tracking a "chain" of declarations + // being checked on the stack, so that we can report the full + // chain that leads from this declaration back to itself. + // sink->diagnose(decl, Diagnostics::cyclicReference, decl); + return; + } + + // Hack: if we are somehow referencing a local variable declaration + // before the line of code that defines it, then we need to diagnose + // an error. + // + // TODO: The right answer is that lookup should have been performed in + // the scope that was in place *before* the variable was declared, but + // this is a quick fix that at least alerts the user to how we are + // interpreting their code. + if (auto varDecl = decl.As<Variable>()) + { + if (auto parenScope = varDecl->ParentDecl->As<ScopeDecl>()) + { + // TODO: This diagnostic should be emitted on the line that is referencing + // the declaration. That requires `EnsureDecl` to take the requesting + // location as a parameter. + sink->diagnose(decl, Diagnostics::localVariableUsedBeforeDeclared, decl); + return; + } } if (DeclCheckState::CheckingHeader > decl->checkState) @@ -2151,7 +2177,7 @@ namespace Slang { for (auto decl : declGroup->decls) { - checkDecl(decl); + DeclVisitor::dispatch(decl); } } @@ -2808,6 +2834,7 @@ namespace Slang stmt->varDecl->type.type = getSession()->getIntType(); addModifier(stmt->varDecl, new ConstModifier()); + stmt->varDecl->SetCheckState(DeclCheckState::Checked); RefPtr<IntVal> rangeBeginVal; RefPtr<IntVal> rangeEndVal; diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index 7227156fa..bae501a3c 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -198,7 +198,8 @@ DIAGNOSTIC(33070, Error, expectedFunction, "expression preceding parenthesis of DIAGNOSTIC(30300, Error, assocTypeInInterfaceOnly, "'associatedtype' can only be defined in an 'interface'.") DIAGNOSTIC(30301, Error, globalGenParamInGlobalScopeOnly, "'__generic_param' can only be defined global scope.") // TODO: need to assign numbers to all these extra diagnostics... -DIAGNOSTIC(39999, Error, cyclicReference, "cyclic reference '$0'.") +DIAGNOSTIC(39999, Fatal, cyclicReference, "cyclic reference '$0'.") +DIAGNOSTIC(39999, Fatal, localVariableUsedBeforeDeclared, "local variable '$0' is being used before its declaration.") DIAGNOSTIC(39999, Error, expectedIntegerConstantWrongType, "expected integer constant (found: '$0')") DIAGNOSTIC(39999, Error, expectedIntegerConstantNotConstant, "expression does not evaluate to a compile-time constant") diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 4c9ecf8a8..e4bf251fc 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -1045,6 +1045,12 @@ SLANG_API int spCompile( int anyErrors = req->executeActions(); return anyErrors; } + catch (Slang::AbortCompilationException&) + { + // This should only be thrown if we already emitted a fatal error + // message, so there is no reason to print something else. + return 1; + } catch (...) { req->mSink.diagnose(Slang::SourceLoc(), Slang::Diagnostics::compilationAborted); |
