summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp29
-rw-r--r--source/slang/diagnostic-defs.h3
-rw-r--r--source/slang/slang.cpp6
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);