summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-10-01 09:23:48 -0700
committerGitHub <noreply@github.com>2025-10-01 16:23:48 +0000
commit5793b6d864b572e464dd5e17dc842e99d13d310d (patch)
tree18c67a633385f5db5d9fc673d99ee4b39d42e705
parent4d241f2ccc2b07673615e94ea8e99060cf2da66c (diff)
Misc parser improvements. (#8563)
- Fix bug parsing multiple link-time structs on the same line. Closes #8553. - Fix bug parsing anonymous struct type as function return type in modern syntax. Closes #8558 - Support semantics on modern style param/var declarations.
-rw-r--r--source/slang/slang-parser.cpp17
-rw-r--r--tests/front-end/link-time-struct-same-line.slang9
-rw-r--r--tests/front-end/modern-syntax-semantic.slang11
-rw-r--r--tests/front-end/struct-result-type.slang16
4 files changed, 49 insertions, 4 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index eb1671aa7..c225ff4ee 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -4250,6 +4250,9 @@ static void parseModernVarDeclBaseCommon(Parser* parser, VarDeclBase* decl)
decl->type = parser->ParseTypeExp();
}
+ auto modifiers = _parseOptSemantics(parser);
+ _addModifiers(decl, modifiers);
+
if (AdvanceIf(parser, TokenType::OpAssign))
{
decl->initExpr = parser->ParseInitExpr();
@@ -4351,6 +4354,8 @@ static NodeBase* parseFuncDecl(Parser* parser, void* /*userData*/)
{
parser->PushScope(decl);
parseModernParamList(parser, decl);
+ auto funcScope = parser->currentScope;
+ parser->PopScope();
if (AdvanceIf(parser, "throws"))
{
decl->errorType = parser->ParseTypeExp();
@@ -4359,8 +4364,6 @@ static NodeBase* parseFuncDecl(Parser* parser, void* /*userData*/)
{
decl->returnType = parser->ParseTypeExp();
}
- auto funcScope = parser->currentScope;
- parser->PopScope();
maybeParseGenericConstraints(parser, genericParent);
parser->PushScope(funcScope);
decl->body = parseOptBody(parser);
@@ -5509,10 +5512,16 @@ Decl* Parser::ParseStruct()
rs->wrappedType = ParseTypeExp();
PushScope(rs);
PopScope();
- ReadToken(TokenType::Semicolon);
+ if (!LookAheadToken(TokenType::Semicolon))
+ {
+ this->diagnose(
+ this->tokenReader.peekToken().loc,
+ Diagnostics::unexpectedTokenExpectedTokenType,
+ "';'");
+ }
return rs;
}
- if (AdvanceIf(this, TokenType::Semicolon))
+ if (LookAheadToken(TokenType::Semicolon))
{
rs->hasBody = false;
return rs;
diff --git a/tests/front-end/link-time-struct-same-line.slang b/tests/front-end/link-time-struct-same-line.slang
new file mode 100644
index 000000000..790e1e165
--- /dev/null
+++ b/tests/front-end/link-time-struct-same-line.slang
@@ -0,0 +1,9 @@
+// Check that we can correctly parse link-time struct definitions on the same line.
+// There was a bug where the parser is expecting an identifier after `struct` definition,
+// even if the struct is a link-time struct ending with a `;`.
+
+//TEST:SIMPLE: -target slangvm
+
+interface IFoo{}
+struct FooImpl : IFoo{}
+export struct Foo1 : IFoo = FooImpl; export struct Foo2 : IFoo = FooImpl; \ No newline at end of file
diff --git a/tests/front-end/modern-syntax-semantic.slang b/tests/front-end/modern-syntax-semantic.slang
new file mode 100644
index 000000000..6ff85c29c
--- /dev/null
+++ b/tests/front-end/modern-syntax-semantic.slang
@@ -0,0 +1,11 @@
+//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK): -output-using-type
+
+//TEST_INPUT: set outputBuffer = out ubuffer(data=[0], stride=4)
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(1,1,1)]
+func computeMain(tid : int : SV_DispatchThreadID) -> void
+{
+ // CHECK: 1
+ outputBuffer[0] = tid + 1;
+} \ No newline at end of file
diff --git a/tests/front-end/struct-result-type.slang b/tests/front-end/struct-result-type.slang
new file mode 100644
index 000000000..35919a78a
--- /dev/null
+++ b/tests/front-end/struct-result-type.slang
@@ -0,0 +1,16 @@
+// Check that we can parse and check an anonymous struct declaration as function return type.
+
+//TEST:INTERPRET(filecheck=CHECK):
+
+module testa;
+
+func test(int a) -> struct{ int a,b; } {
+ return {a,2};
+}
+
+void main()
+{
+ let m = test(1);
+ // CHECK: 3
+ printf("%d\n", m.a + m.b);
+}