summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-parser.cpp')
-rw-r--r--source/slang/slang-parser.cpp45
1 files changed, 40 insertions, 5 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 1a7845a25..1fd8bffcc 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -190,7 +190,7 @@ namespace Slang
void parseSourceFile(ContainerDecl* parentDecl);
Decl* ParseStruct();
ClassDecl* ParseClass();
- GLSLInterfaceBlockDecl* ParseGLSLInterfaceBlock();
+ Decl* ParseGLSLInterfaceBlock();
Stmt* ParseStatement(Stmt* parentStmt = nullptr);
Stmt* parseBlockStatement();
Stmt* parseLabelStatement();
@@ -2379,6 +2379,15 @@ namespace Slang
}
}
+ static String _wrappingModifierType(const WrappingTypeModifier* mod)
+ {
+ if(as<GLSLBufferModifier>(mod))
+ {
+ return "GLSLShaderStorageBuffer";
+ }
+ SLANG_UNREACHABLE("unhandled wrapping type modifier");
+ }
+
/// Apply any type modifier in `ioBaseModifiers` to the given `typeExpr`.
///
/// If any type modifiers were present, `ioBaseModifiers` will be updated
@@ -2424,6 +2433,30 @@ namespace Slang
//
baseModifierLink = &baseModifier->next;
}
+ else if(const auto wrappingTypeModifier = as<WrappingTypeModifier>(typeModifier))
+ {
+ // This is where we match things which are modifiers in the
+ // syntax, but we match conceptually as wrappers around a type
+ // expression
+
+ // Firstly, disptach the modifier, we don't need it again
+ baseModifierLink = &baseModifier->next;
+
+ // Conjure up the generic wrapper type
+ // Make sure to use the outer scope, to avoid user name shadowing
+ auto bufferWrapperTypeExpr = parser->astBuilder->create<VarExpr>();
+ bufferWrapperTypeExpr->loc = wrappingTypeModifier->loc;
+ bufferWrapperTypeExpr->name = getName(parser, _wrappingModifierType(wrappingTypeModifier));
+ bufferWrapperTypeExpr->scope = parser->outerScope;
+
+ // Apply the wrapper
+ auto bufferPointerTypeExpr = parser->astBuilder->create<GenericAppExpr>();
+ bufferPointerTypeExpr->loc = wrappingTypeModifier->loc;
+ bufferPointerTypeExpr->functionExpr = bufferWrapperTypeExpr;
+ bufferPointerTypeExpr->arguments.add(typeExpr);
+
+ typeExpr = bufferPointerTypeExpr;
+ }
else
{
// If we have a type modifier, we need to graft it onto
@@ -2533,9 +2566,10 @@ namespace Slang
&& parser->LookAheadToken(TokenType::Identifier)
&& parser->LookAheadToken(TokenType::LBrace,1) )
{
- auto decl = parser->ParseGLSLInterfaceBlock();
- typeSpec.decl = decl;
- typeSpec.expr = createDeclRefType(parser, decl);
+ // Parse the struct-like part
+ auto innerStructDecl = parser->ParseGLSLInterfaceBlock();
+ typeSpec.decl = innerStructDecl;
+ typeSpec.expr = createDeclRefType(parser, typeSpec.decl);
return typeSpec;
}
else if(parser->LookAheadToken("enum"))
@@ -4589,11 +4623,12 @@ namespace Slang
return rs;
}
- GLSLInterfaceBlockDecl* Parser::ParseGLSLInterfaceBlock()
+ Decl* Parser::ParseGLSLInterfaceBlock()
{
//
// MyBlockName { float myData[]; } myBufferName;
//
+ // This returns a struct decl representing the fields
auto* rs = astBuilder->create<GLSLInterfaceBlockDecl>();
FillPosition(rs);