summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-07-14 18:51:57 -0700
committerGitHub <noreply@github.com>2025-07-15 01:51:57 +0000
commit37143802781d8d480361d7c23202347ae3acf094 (patch)
tree300a6f60f2ddd3a0d7f14ab07665dfff5d67f31c /source
parentdb06fbb163877b8823507b162ee7f2dfca8520f0 (diff)
Fix language server crash. (#7756)
* Fix language server crash. * Fix tests. * Fix. * Revert changes.
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-decl.cpp3
-rw-r--r--source/slang/slang-parser.cpp82
-rw-r--r--source/slang/slang-syntax.cpp8
3 files changed, 46 insertions, 47 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index e67962ca3..584b1f081 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -9672,9 +9672,8 @@ void SemanticsVisitor::checkForRedeclaration(Decl* decl)
// Sanity check: there should always be a parent declaration.
//
- SLANG_ASSERT(parentDecl);
if (!parentDecl)
- return;
+ SLANG_ABORT_COMPILATION("decl has no parent.");
// If the declaration is the "inner" declaration of a generic,
// then we actually want to look one level up, because the
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 6401b3d06..0efa6a4b3 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -1859,53 +1859,46 @@ static Stmt* parseOptBody(Parser* parser)
}
}
- if (parser->getStage() == ParsingStage::Decl)
- {
- // If we are at the initial parsing stage, just collect the tokens
- // without actually parsing them.
- if (peekTokenType(parser) != TokenType::LBrace)
- {
- return parser->parseBlockStatement();
- }
- auto unparsedStmt = parser->astBuilder->create<UnparsedStmt>();
- unparsedStmt->currentScope = parser->currentScope;
- unparsedStmt->outerScope = parser->outerScope;
- unparsedStmt->sourceLanguage = parser->getSourceLanguage();
- unparsedStmt->isInVariadicGenerics = parser->isInVariadicGenerics;
- parser->FillPosition(unparsedStmt);
- List<Token>& tokens = unparsedStmt->tokens;
- int braceDepth = 0;
- for (;;)
+ // If we are at the initial parsing stage, just collect the tokens
+ // without actually parsing them.
+ if (peekTokenType(parser) != TokenType::LBrace)
+ {
+ return parser->parseBlockStatement();
+ }
+ auto unparsedStmt = parser->astBuilder->create<UnparsedStmt>();
+ unparsedStmt->currentScope = parser->currentScope;
+ unparsedStmt->outerScope = parser->outerScope;
+ unparsedStmt->sourceLanguage = parser->getSourceLanguage();
+ unparsedStmt->isInVariadicGenerics = parser->isInVariadicGenerics;
+ parser->FillPosition(unparsedStmt);
+ List<Token>& tokens = unparsedStmt->tokens;
+ int braceDepth = 0;
+ for (;;)
+ {
+ auto token = parser->ReadToken();
+ if (token.type == TokenType::EndOfFile)
{
- auto token = parser->ReadToken();
- if (token.type == TokenType::EndOfFile)
- {
- break;
- }
- if (token.type == TokenType::LBrace)
- {
- braceDepth++;
- }
- else if (token.type == TokenType::RBrace)
- {
- braceDepth--;
- }
- tokens.add(token);
- if (braceDepth == 0)
- {
- break;
- }
+ break;
+ }
+ if (token.type == TokenType::LBrace)
+ {
+ braceDepth++;
+ }
+ else if (token.type == TokenType::RBrace)
+ {
+ braceDepth--;
+ }
+ tokens.add(token);
+ if (braceDepth == 0)
+ {
+ break;
}
- Token eofToken;
- eofToken.type = TokenType::EndOfFile;
- eofToken.loc = parser->tokenReader.peekLoc();
- tokens.add(eofToken);
- return unparsedStmt;
}
-
- // If we are in the second stage of parsing, then we need to actually
- // parse the block statement for real.
- return parser->parseBlockStatement();
+ Token eofToken;
+ eofToken.type = TokenType::EndOfFile;
+ eofToken.loc = parser->tokenReader.peekLoc();
+ tokens.add(eofToken);
+ return unparsedStmt;
}
/// Complete parsing of a function using traditional (C-like) declarator syntax
@@ -5500,7 +5493,6 @@ static EnumCaseDecl* parseEnumCaseDecl(Parser* parser)
static Decl* parseEnumDecl(Parser* parser)
{
EnumDecl* decl = parser->astBuilder->create<EnumDecl>();
-
parser->ReadToken("enum");
// HACK: allow the user to write `enum class` in case
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index bb5b574bb..67d562f0f 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -912,11 +912,19 @@ FuncType* getFuncType(ASTBuilder* astBuilder, DeclRef<CallableDecl> const& declR
{
List<Type*> paramTypes;
auto resultType = getResultType(astBuilder, declRef);
+
+ if (!resultType)
+ resultType = astBuilder->getErrorType();
+
auto errorType = getErrorCodeType(astBuilder, declRef);
auto visitParamDecl = [&](DeclRef<ParamDecl> paramDeclRef)
{
auto paramDecl = paramDeclRef.getDecl();
auto paramType = getParamType(astBuilder, paramDeclRef);
+ if (!paramType)
+ {
+ paramType = astBuilder->getErrorType();
+ }
if (paramDecl->findModifier<RefModifier>())
{
paramType = astBuilder->getRefType(paramType, AddressSpace::Generic);