summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-02-06 01:03:42 -0800
committerGitHub <noreply@github.com>2024-02-06 01:03:42 -0800
commitb301c93753eaddb4571999f209cb8c1faa2fe205 (patch)
tree72fef2e499abecad0dda5ba2347e5890346ac173 /source
parent23c65b873f8002b74d60f61cacb3614da60e078d (diff)
Unify GLSL and HLSL buffer block parsing. (#3552)
* Unify GLSL and HLSL buffer block parsing. Automatic GLSL module recognition. * Fix.
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang5
-rw-r--r--source/slang/hlsl.meta.slang5
-rw-r--r--source/slang/slang-ast-modifier.h20
-rw-r--r--source/slang/slang-check-modifier.cpp3
-rw-r--r--source/slang/slang-emit-glsl.cpp34
-rw-r--r--source/slang/slang-ir-lower-glsl-ssbo-types.cpp6
-rw-r--r--source/slang/slang-ir.h8
-rw-r--r--source/slang/slang-lower-to-ir.cpp2
-rw-r--r--source/slang/slang-parser.cpp212
-rw-r--r--source/slang/slang-parser.h1
-rw-r--r--source/slang/slang-preprocessor.cpp12
-rw-r--r--source/slang/slang-preprocessor.h6
-rw-r--r--source/slang/slang.cpp48
13 files changed, 229 insertions, 133 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 3961403e7..f3ab38582 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1296,11 +1296,6 @@ struct Primitives
}
};
-__generic<T>
-__intrinsic_type($(kIROp_GLSLShaderStorageBufferType))
-__magic_type(GLSLShaderStorageBufferType)
-struct GLSLShaderStorageBuffer {}
-
//@ hidden:
// Need to add constructors to the types above
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index a485c6514..273cfdc4f 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -27,6 +27,11 @@ __intrinsic_type($(kIROp_ScalarBufferLayoutType))
struct ScalarDataLayout : IBufferDataLayout
{};
+__generic<T, L : IBufferDataLayout = DefaultDataLayout>
+__intrinsic_type($(kIROp_GLSLShaderStorageBufferType))
+__magic_type(GLSLShaderStorageBufferType)
+struct GLSLShaderStorageBuffer {}
+
__generic<T,L:IBufferDataLayout>
__intrinsic_op($(kIROp_StructuredBufferGetDimensions))
uint2 __structuredBufferGetDimensions(AppendStructuredBuffer<T,L> buffer);
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index dae8966de..155363e0c 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -243,6 +243,26 @@ class GLSLLocationLayoutModifier : public GLSLParsedLayoutModifier
SLANG_AST_CLASS(GLSLLocationLayoutModifier)
};
+class GLSLBufferDataLayoutModifier : public GLSLParsedLayoutModifier
+{
+ SLANG_AST_CLASS(GLSLBufferDataLayoutModifier)
+};
+
+class GLSLStd140Modifier : public GLSLBufferDataLayoutModifier
+{
+ SLANG_AST_CLASS(GLSLStd140Modifier)
+};
+
+class GLSLStd430Modifier : public GLSLBufferDataLayoutModifier
+{
+ SLANG_AST_CLASS(GLSLStd430Modifier)
+};
+
+class GLSLScalarModifier : public GLSLBufferDataLayoutModifier
+{
+ SLANG_AST_CLASS(GLSLScalarModifier)
+};
+
// A catch-all for single-keyword modifiers
class SimpleModifier : public Modifier
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 51cb5346a..2627ab8e8 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -1045,6 +1045,7 @@ namespace Slang
// layout(local_size_x=1) in;
case ASTNodeType::InModifier:
case ASTNodeType::InOutModifier:
+ case ASTNodeType::OutModifier:
case ASTNodeType::GLSLLayoutModifier:
case ASTNodeType::GLSLParsedLayoutModifier:
case ASTNodeType::GLSLConstantIDLayoutModifier:
@@ -1059,8 +1060,6 @@ namespace Slang
return true;
[[fallthrough]];
- // Allowed only on parameters and global variables.
- case ASTNodeType::OutModifier:
case ASTNodeType::RefModifier:
case ASTNodeType::ConstRefModifier:
case ASTNodeType::GLSLBufferModifier:
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index bae34b6fa..e394804c7 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -229,7 +229,39 @@ void GLSLSourceEmitter::emitSSBOHeader(IRGlobalParam* varDecl, IRType* bufferTyp
_requireGLSLVersion(430);
m_writer->emit("layout(");
- m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430");
+ IROp layoutOp = kIROp_DefaultBufferLayoutType;
+ if (auto structBufferType = as<IRHLSLStructuredBufferTypeBase>(bufferType))
+ {
+ layoutOp = structBufferType->getDataLayout()? structBufferType->getDataLayout()->getOp() : kIROp_DefaultBufferLayoutType;
+ }
+ else if (auto ssboType = as<IRGLSLShaderStorageBufferType>(bufferType))
+ {
+ layoutOp = ssboType->getDataLayout() ? ssboType->getDataLayout()->getOp() : kIROp_DefaultBufferLayoutType;
+ }
+
+ if (layoutOp == kIROp_DefaultBufferLayoutType)
+ {
+ m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430");
+ }
+ else
+ {
+ switch (layoutOp)
+ {
+ case kIROp_DefaultBufferLayoutType:
+ m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430");
+ break;
+ case kIROp_Std430BufferLayoutType:
+ m_writer->emit("std430");
+ break;
+ case kIROp_Std140BufferLayoutType:
+ m_writer->emit("std140");
+ break;
+ case kIROp_ScalarBufferLayoutType:
+ _requireGLSLExtension(toSlice("GL_EXT_scalar_block_layout"));
+ m_writer->emit("scalar");
+ break;
+ }
+ }
auto layout = getVarLayout(varDecl);
if (layout)
diff --git a/source/slang/slang-ir-lower-glsl-ssbo-types.cpp b/source/slang/slang-ir-lower-glsl-ssbo-types.cpp
index f0bdb7e83..a511c1c06 100644
--- a/source/slang/slang-ir-lower-glsl-ssbo-types.cpp
+++ b/source/slang/slang-ir-lower-glsl-ssbo-types.cpp
@@ -81,11 +81,11 @@ namespace Slang
for(const auto& [ssbo, info] : arrayLikeSSBOTypes)
{
builder.setInsertAfter(ssbo);
- IRInst* operands = info.elementType;
+ IRInst* operands[2] = { info.elementType, ssbo->getDataLayout() };
const auto sb = builder.getType(
kIROp_HLSLRWStructuredBufferType,
- 1,
- &operands
+ 2,
+ operands
);
ssbo->replaceUsesWith(sb);
ssbo->removeAndDeallocate();
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 2193e0351..0766bb168 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1526,9 +1526,15 @@ SIMPLE_IR_TYPE(ConstantBufferType, UniformParameterGroupType)
SIMPLE_IR_TYPE(TextureBufferType, UniformParameterGroupType)
SIMPLE_IR_TYPE(GLSLInputParameterGroupType, VaryingParameterGroupType)
SIMPLE_IR_TYPE(GLSLOutputParameterGroupType, VaryingParameterGroupType)
-SIMPLE_IR_TYPE(GLSLShaderStorageBufferType, ParameterGroupType)
SIMPLE_IR_TYPE(ParameterBlockType, UniformParameterGroupType)
+struct IRGLSLShaderStorageBufferType : IRBuiltinGenericType
+{
+ IRType* getDataLayout() { return (IRType*)getOperand(1); }
+
+ IR_LEAF_ISA(GLSLShaderStorageBufferType)
+};
+
struct IRArrayTypeBase : IRType
{
IRType* getElementType() { return (IRType*)getOperand(0); }
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index e0bf72f7d..427fe1cf0 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -2317,6 +2317,8 @@ static void addNameHint(
String name = getNameForNameHint(context, decl);
if(name.getLength() == 0)
return;
+ if (name == "MyBlockName2")
+ printf("break");
context->irBuilder->addNameHintDecoration(inst, name.getUnownedSlice());
}
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 3940e59cf..4b6d9b2d0 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -2379,15 +2379,6 @@ 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
@@ -2433,30 +2424,6 @@ 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
@@ -2526,7 +2493,7 @@ namespace Slang
}
/// Parse a type specifier, without dealing with modifiers.
- static TypeSpec _parseSimpleTypeSpec(Parser* parser, bool mightBeGLSLInterfaceBlock)
+ static TypeSpec _parseSimpleTypeSpec(Parser* parser)
{
TypeSpec typeSpec;
@@ -2562,16 +2529,6 @@ namespace Slang
typeSpec.expr = createDeclRefType(parser, decl);
return typeSpec;
}
- else if( mightBeGLSLInterfaceBlock
- && parser->LookAheadToken(TokenType::Identifier)
- && parser->LookAheadToken(TokenType::LBrace,1) )
- {
- // 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"))
{
auto decl = parseEnumDecl(parser);
@@ -2629,17 +2586,17 @@ namespace Slang
return typeSpec;
}
- static bool hasPotentialGLSLInterfaceBlockModifier(Parser* parser, Modifiers& mods)
+ static Modifier* findPotentialGLSLInterfaceBlockModifier(Parser* parser, Modifiers& mods)
{
if (!parser->options.allowGLSLInput)
- return false;
+ return nullptr;
for (auto mod : mods)
{
- if (as<GLSLBufferModifier>(mod) || as<InModifier>(mod) || as<OutModifier>(mod))
- return true;
+ if (as<HLSLUniformModifier>(mod) || as<InModifier>(mod) || as<OutModifier>(mod))
+ return mod;
}
- return false;
+ return nullptr;
}
/// Parse a type specifier, following the given list of modifiers.
@@ -2650,7 +2607,7 @@ namespace Slang
///
static TypeSpec _parseTypeSpec(Parser* parser, Modifiers& ioModifiers)
{
- TypeSpec typeSpec = _parseSimpleTypeSpec(parser, hasPotentialGLSLInterfaceBlockModifier(parser, ioModifiers));
+ TypeSpec typeSpec = _parseSimpleTypeSpec(parser);
// We don't know whether `ioModifiers` has any modifiers in it,
// or which of them might be type modifiers, so we will delegate
@@ -2675,7 +2632,7 @@ namespace Slang
static TypeSpec _parseTypeSpec(Parser* parser)
{
Modifiers modifiers = ParseModifiers(parser);
- TypeSpec typeSpec = _parseSimpleTypeSpec(parser, hasPotentialGLSLInterfaceBlockModifier(parser, modifiers));
+ TypeSpec typeSpec = _parseSimpleTypeSpec(parser);
typeSpec = _applyModifiersToTypeSpec(parser, typeSpec, modifiers);
@@ -3094,9 +3051,10 @@ namespace Slang
_addModifiers(decl, _parseOptSemantics(parser));
}
- static Decl* ParseHLSLBufferDecl(
+ static Decl* ParseBufferBlockDecl(
Parser* parser,
- String bufferWrapperTypeName)
+ String bufferWrapperTypeName,
+ String *additionalTypeArg = nullptr)
{
// An HLSL declaration of a constant buffer like this:
//
@@ -3161,23 +3119,37 @@ namespace Slang
bufferDataTypeExpr->name = bufferDataTypeDecl->nameAndLoc.name;
bufferDataTypeExpr->scope = parser->currentScope;
- // Construct a type expression to reference the type constructor
- auto bufferWrapperTypeExpr = parser->astBuilder->create<VarExpr>();
- bufferWrapperTypeExpr->loc = bufferWrapperTypeNamePos;
- bufferWrapperTypeExpr->name = getName(parser, bufferWrapperTypeName);
-
- // Always need to look this up in the outer scope,
- // so that it won't collide with, e.g., a local variable called `ConstantBuffer`
- bufferWrapperTypeExpr->scope = parser->outerScope;
-
// Construct a type expression that represents the type for the variable,
// which is the wrapper type applied to the data type
- auto bufferVarTypeExpr = parser->astBuilder->create<GenericAppExpr>();
- bufferVarTypeExpr->loc = bufferVarDecl->loc;
- bufferVarTypeExpr->functionExpr = bufferWrapperTypeExpr;
- bufferVarTypeExpr->arguments.add(bufferDataTypeExpr);
+ if (bufferWrapperTypeName.getLength())
+ {
+ // Construct a type expression to reference the type constructor
+ auto bufferWrapperTypeExpr = parser->astBuilder->create<VarExpr>();
+ bufferWrapperTypeExpr->loc = bufferWrapperTypeNamePos;
+ bufferWrapperTypeExpr->name = getName(parser, bufferWrapperTypeName);
+
+ // Always need to look this up in the outer scope,
+ // so that it won't collide with, e.g., a local variable called `ConstantBuffer`
+ bufferWrapperTypeExpr->scope = parser->outerScope;
- bufferVarDecl->type.exp = bufferVarTypeExpr;
+ auto bufferVarTypeExpr = parser->astBuilder->create<GenericAppExpr>();
+ bufferVarTypeExpr->loc = bufferVarDecl->loc;
+ bufferVarTypeExpr->functionExpr = bufferWrapperTypeExpr;
+ bufferVarTypeExpr->arguments.add(bufferDataTypeExpr);
+ if (additionalTypeArg)
+ {
+ auto additionalArgExpr = parser->astBuilder->create<VarExpr>();
+ additionalArgExpr->scope = parser->outerScope;
+ additionalArgExpr->loc = SourceLoc();
+ additionalArgExpr->name = getName(parser, *additionalTypeArg);
+ bufferVarTypeExpr->arguments.add(additionalArgExpr);
+ }
+ bufferVarDecl->type.exp = bufferVarTypeExpr;
+ }
+ else
+ {
+ bufferVarDecl->type.exp = bufferDataTypeExpr;
+ }
// Any semantics applied to the buffer declaration are taken as applying
// to the variable instead.
@@ -3191,6 +3163,7 @@ namespace Slang
{
// If the user specified an explicit name of the buffer var, use it.
bufferVarDecl->nameAndLoc = ParseDeclName(parser);
+ reflectionNameModifier->nameAndLoc = bufferVarDecl->nameAndLoc;
parser->ReadToken(TokenType::Semicolon);
}
else
@@ -3227,13 +3200,19 @@ namespace Slang
static NodeBase* parseHLSLCBufferDecl(
Parser* parser, void* /*userData*/)
{
- return ParseHLSLBufferDecl(parser, "ConstantBuffer");
+ return ParseBufferBlockDecl(parser, "ConstantBuffer");
}
static NodeBase* parseHLSLTBufferDecl(
Parser* parser, void* /*userData*/)
{
- return ParseHLSLBufferDecl(parser, "TextureBuffer");
+ return ParseBufferBlockDecl(parser, "TextureBuffer");
+ }
+
+ static NodeBase* parseGLSLShaderStorageBufferDecl(
+ Parser* parser, String layoutType)
+ {
+ return ParseBufferBlockDecl(parser, "GLSLShaderStorageBuffer", &layoutType);
}
static void parseOptionalInheritanceClause(Parser* parser, AggTypeDeclBase* decl)
@@ -4442,6 +4421,55 @@ namespace Slang
break;
}
+ // This can also be a GLSL style buffer block declaration.
+ if (parser->options.allowGLSLInput)
+ {
+ auto getLayoutArg = [&](const char* defaultLayout)
+ {
+ if (auto dataLayoutMod = modifiers.findModifier<GLSLBufferDataLayoutModifier>())
+ {
+ if (as<GLSLStd140Modifier>(dataLayoutMod))
+ return "Std140DataLayout";
+ else if (as<GLSLStd430Modifier>(dataLayoutMod))
+ return "Std430DataLayout";
+ else if (as<GLSLScalarModifier>(dataLayoutMod))
+ return "ScalarDataLayout";
+ }
+ return defaultLayout;
+ };
+ if (AdvanceIf(parser, "buffer"))
+ {
+ decl = as<Decl>(parseGLSLShaderStorageBufferDecl(parser, getLayoutArg("Std430DataLayout")));
+ break;
+ }
+ else if (auto mod = findPotentialGLSLInterfaceBlockModifier(parser, modifiers))
+ {
+ if (!parser->LookAheadToken(TokenType::LBrace, 1))
+ {
+ goto endOfGlslBufferBlock;
+ }
+
+ if (as<HLSLUniformModifier>(mod))
+ {
+ decl = as<Decl>(parseHLSLCBufferDecl(parser, nullptr));
+ break;
+ }
+ else
+ {
+ bool isGLSLBuiltinRedeclaration = parser->tokenReader.peekToken().getContent().startsWith("gl_");
+ decl = ParseBufferBlockDecl(parser, "", nullptr);
+ if (isGLSLBuiltinRedeclaration)
+ {
+ // Ignore builtin redeclaration.
+ decl = parser->astBuilder->create<EmptyDecl>();
+ decl->loc = loc;
+ }
+ break;
+ }
+ }
+ endOfGlslBufferBlock:;
+ }
+
// Our final fallback case is to assume that the user is
// probably writing a C-style declarator-based declaration.
decl = ParseDeclaratorDecl(parser, containerDecl, modifiers);
@@ -4548,34 +4576,6 @@ namespace Slang
parser->ReadToken(TokenType::Semicolon);
return true;
}
-
- Modifier* layoutModifier = nullptr;
- if (parser->LookAheadToken("layout"))
- {
- tryParseUsingSyntaxDecl<Modifier>(parser, &layoutModifier);
- }
-
- DeclBase* decl = nullptr;
- if (parser->LookAheadToken("uniform", 0) &&
- (parser->LookAheadToken(TokenType::LBrace, 1) ||
- parser->LookAheadToken(TokenType::Identifier, 1) &&
- parser->LookAheadToken(TokenType::LBrace, 2)))
- {
- parser->ReadToken();
- decl = as<Decl>(parseHLSLCBufferDecl(parser, containerDecl));
- if (decl)
- AddMember(parser->currentScope, (Decl*)decl);
- }
- else if (layoutModifier)
- {
- decl = ParseDecl(parser, containerDecl);
- }
-
- if (decl)
- {
- addModifier(decl, layoutModifier);
- return true;
- }
return false;
}
@@ -7333,7 +7333,7 @@ namespace Slang
// If there are any modifiers, then we know that we are actually
// in the type case.
//
- auto typeSpec = _parseSimpleTypeSpec(parser, false);
+ auto typeSpec = _parseSimpleTypeSpec(parser);
typeSpec = _applyModifiersToTypeSpec(parser, typeSpec, modifiers);
auto typeExpr = typeSpec.expr;
@@ -7355,7 +7355,9 @@ namespace Slang
NamePool* namePool,
SourceLanguage sourceLanguage)
{
- Parser parser(astBuilder, tokens, sink, outerScope, ParserOptions{});
+ ParserOptions options;
+ options.allowGLSLInput = sourceLanguage == SourceLanguage::GLSL;
+ Parser parser(astBuilder, tokens, sink, outerScope, options);
parser.currentScope = outerScope;
parser.namePool = namePool;
parser.sourceLanguage = sourceLanguage;
@@ -7366,6 +7368,7 @@ namespace Slang
void parseSourceFile(
ASTBuilder* astBuilder,
TranslationUnitRequest* translationUnit,
+ SourceLanguage sourceLanguage,
TokenSpan const& tokens,
DiagnosticSink* sink,
Scope* outerScope,
@@ -7373,8 +7376,9 @@ namespace Slang
{
ParserOptions options = {};
options.enableEffectAnnotations = translationUnit->compileRequest->getLinkage()->getEnableEffectAnnotations();
- options.allowGLSLInput = translationUnit->compileRequest->getLinkage()->getAllowGLSLInput() ||
- translationUnit->sourceLanguage == SourceLanguage::GLSL;
+ options.allowGLSLInput =
+ translationUnit->compileRequest->getLinkage()->getAllowGLSLInput() ||
+ sourceLanguage == SourceLanguage::GLSL;
options.isInLanguageServer = translationUnit->compileRequest->getLinkage()->isInLanguageServer();
Parser parser(astBuilder, tokens, sink, outerScope, options);
@@ -7701,7 +7705,10 @@ namespace Slang
#define CASE(key, type) if (nameText == #key) { modifier = parser->astBuilder->create<type>(); } else
CASE(push_constant, PushConstantAttribute)
CASE(shaderRecordNV, ShaderRecordAttribute)
- CASE(constant_id, GLSLConstantIDLayoutModifier)
+ CASE(constant_id, GLSLConstantIDLayoutModifier)
+ CASE(std140, GLSLStd140Modifier)
+ CASE(std430, GLSLStd430Modifier)
+ CASE(scalar, GLSLScalarModifier)
CASE(location, GLSLLocationLayoutModifier)
{
modifier = parser->astBuilder->create<GLSLUnparsedLayoutModifier>();
@@ -7941,7 +7948,6 @@ namespace Slang
_makeParseModifier("uniform", HLSLUniformModifier::kReflectClassInfo),
_makeParseModifier("volatile", HLSLVolatileModifier::kReflectClassInfo),
_makeParseModifier("export", HLSLExportModifier::kReflectClassInfo),
- _makeParseModifier("buffer", GLSLBufferModifier::kReflectClassInfo),
// Modifiers for geometry shader input
_makeParseModifier("point", HLSLPointModifier::kReflectClassInfo),
diff --git a/source/slang/slang-parser.h b/source/slang/slang-parser.h
index 9933f6839..22b3e73ce 100644
--- a/source/slang/slang-parser.h
+++ b/source/slang/slang-parser.h
@@ -12,6 +12,7 @@ namespace Slang
void parseSourceFile(
ASTBuilder* astBuilder,
TranslationUnitRequest* translationUnit,
+ SourceLanguage sourceLanguage,
TokenSpan const& tokens,
DiagnosticSink* sink,
Scope* outerScope,
diff --git a/source/slang/slang-preprocessor.cpp b/source/slang/slang-preprocessor.cpp
index 02f46103b..9586088a1 100644
--- a/source/slang/slang-preprocessor.cpp
+++ b/source/slang/slang-preprocessor.cpp
@@ -1015,6 +1015,9 @@ struct Preprocessor
/// Stores the initiating macro source location.
SourceLoc initiatingMacroSourceLoc;
+ /// Detected source language.
+ SourceLanguage language = SourceLanguage::Unknown;
+
/// Stores macro definition and invocation info for language server.
PreprocessorContentAssistInfo* contentAssistInfo = nullptr;
@@ -3655,6 +3658,7 @@ static void HandleVersionDirective(PreprocessorDirectiveContext* context)
}
SkipToEndOfLine(context);
+ context->m_preprocessor->language = SourceLanguage::GLSL;
// TODO, just skip the version for now
}
@@ -4022,6 +4026,7 @@ TokenList preprocessSource(
IncludeSystem* includeSystem,
Dictionary<String, String> const& defines,
Linkage* linkage,
+ SourceLanguage& outDetectedLanguage,
PreprocessorHandler* handler)
{
PreprocessorDesc desc;
@@ -4040,12 +4045,13 @@ TokenList preprocessSource(
{
desc.contentAssistInfo = &linkage->contentAssistInfo.preprocessorInfo;
}
- return preprocessSource(file, desc);
+ return preprocessSource(file, desc, outDetectedLanguage);
}
TokenList preprocessSource(
SourceFile* file,
- PreprocessorDesc const& desc)
+ PreprocessorDesc const& desc,
+ SourceLanguage &outDetectedLanguage)
{
using namespace preprocessor;
@@ -4132,6 +4138,8 @@ TokenList preprocessSource(
String s = sb.produceString();
#endif
+ outDetectedLanguage = preprocessor.language;
+
return tokens;
}
diff --git a/source/slang/slang-preprocessor.h b/source/slang/slang-preprocessor.h
index c37fd1607..d8698cd01 100644
--- a/source/slang/slang-preprocessor.h
+++ b/source/slang/slang-preprocessor.h
@@ -13,6 +13,8 @@ class DiagnosticSink;
class Linkage;
struct PreprocessorContentAssistInfo;
+enum class SourceLanguage : SlangSourceLanguageIntegral;
+
namespace preprocessor
{
struct Preprocessor;
@@ -62,7 +64,8 @@ struct PreprocessorDesc
/// Take a source `file` and preprocess it into a list of tokens.
TokenList preprocessSource(
SourceFile* file,
- PreprocessorDesc const& desc);
+ PreprocessorDesc const& desc,
+ SourceLanguage& outDetectedLanguage);
/// Convenience wrapper for `preprocessSource` when a `Linkage` is available
TokenList preprocessSource(
@@ -71,6 +74,7 @@ TokenList preprocessSource(
IncludeSystem* includeSystem,
Dictionary<String, String> const& defines,
Linkage* linkage,
+ SourceLanguage& outDetectedLanguage,
PreprocessorHandler* handler = nullptr);
// The following functions are intended to be used inside of implementations
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index e99f94484..267d91173 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1984,17 +1984,23 @@ Expr* Linkage::parseTermString(String typeStr, Scope* scope)
// We need to temporarily replace the SourceManager for this CompileRequest
ScopeReplaceSourceManager scopeReplaceSourceManager(this, &localSourceManager);
+
+ SourceLanguage sourceLanguage;
auto tokens = preprocessSource(
srcFile,
&sink,
nullptr,
Dictionary<String,String>(),
- this);
+ this,
+ sourceLanguage);
+
+ if (sourceLanguage == SourceLanguage::Unknown)
+ sourceLanguage = SourceLanguage::Slang;
return parseTermFromSourceFile(
getASTBuilder(),
- tokens, &sink, scope, getNamePool(), SourceLanguage::Slang);
+ tokens, &sink, scope, getNamePool(), sourceLanguage);
}
Type* checkProperType(
@@ -2349,19 +2355,6 @@ void FrontEndCompileRequest::parseTranslationUnit(
// would be checked too (after those on the FrontEndCompileRequest).
IncludeSystem includeSystem(&linkage->searchDirectories, linkage->getFileSystemExt(), linkage->getSourceManager());
- Scope* languageScope = nullptr;
- switch (translationUnit->sourceLanguage)
- {
- case SourceLanguage::HLSL:
- languageScope = getSession()->hlslLanguageScope;
- break;
-
- case SourceLanguage::Slang:
- default:
- languageScope = getSession()->slangLanguageScope;
- break;
- }
-
auto combinedPreprocessorDefinitions = translationUnit->getCombinedPreprocessorDefinitions();
auto module = translationUnit->getModule();
@@ -2406,14 +2399,32 @@ void FrontEndCompileRequest::parseTranslationUnit(
for (auto sourceFile : translationUnit->getSourceFiles())
{
+ SourceLanguage sourceLanguage = SourceLanguage::Unknown;
auto tokens = preprocessSource(
sourceFile,
getSink(),
&includeSystem,
combinedPreprocessorDefinitions,
getLinkage(),
+ sourceLanguage,
&preprocessorHandler);
+ if (sourceLanguage == SourceLanguage::Unknown)
+ sourceLanguage = translationUnit->sourceLanguage;
+
+ Scope* languageScope = nullptr;
+ switch (sourceLanguage)
+ {
+ case SourceLanguage::HLSL:
+ languageScope = getSession()->hlslLanguageScope;
+ break;
+
+ case SourceLanguage::Slang:
+ default:
+ languageScope = getSession()->slangLanguageScope;
+ break;
+ }
+
if (outputIncludes)
{
_outputIncludes(translationUnit->getSourceFiles(), getSink()->getSourceManager(), getSink());
@@ -2432,6 +2443,7 @@ void FrontEndCompileRequest::parseTranslationUnit(
parseSourceFile(
astBuilder,
translationUnit,
+ sourceLanguage,
tokens,
getSink(),
languageScope,
@@ -3420,18 +3432,24 @@ Linkage::IncludeResult Linkage::findAndIncludeFile(Module* module, TranslationUn
FrontEndPreprocessorHandler preprocessorHandler(module, module->getASTBuilder(), sink);
auto combinedPreprocessorDefinitions = translationUnit->getCombinedPreprocessorDefinitions();
+ SourceLanguage sourceLanguage = SourceLanguage::Unknown;
auto tokens = preprocessSource(
sourceFile,
sink,
&includeSystem,
combinedPreprocessorDefinitions,
this,
+ sourceLanguage,
&preprocessorHandler);
+
+ if (sourceLanguage == SourceLanguage::Unknown)
+ sourceLanguage = translationUnit->sourceLanguage;
auto outerScope = module->getModuleDecl()->ownedScope;
parseSourceFile(
module->getASTBuilder(),
translationUnit,
+ sourceLanguage,
tokens,
sink,
outerScope,