HLSL: cbuffer and tbuffer grammar and production.

This commit is contained in:
John Kessenich 2016-07-25 16:05:33 -06:00
parent b8d2a006d1
commit 3d157c510f
9 changed files with 268 additions and 46 deletions

View File

@ -0,0 +1,153 @@
hlsl.buffer.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:23 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
0:20 Function Parameters:
0:20 'input' (in 4-component vector of float)
0:? Sequence
0:21 Branch: Return with expression
0:21 add (temp 4-component vector of float)
0:21 add (temp 4-component vector of float)
0:21 add (temp 4-component vector of float)
0:21 'input' (in 4-component vector of float)
0:21 v1: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
0:21 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
0:21 Constant:
0:21 0 (const uint)
0:21 add (temp 4-component vector of float)
0:21 v2: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
0:21 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
0:21 Constant:
0:21 0 (const uint)
0:21 v3: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
0:21 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
0:21 Constant:
0:21 0 (const uint)
0:21 v4: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
0:21 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
0:21 Constant:
0:21 0 (const uint)
0:? Linker Objects
0:? 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
0:? 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
0:? 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
0:? 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:23 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
0:20 Function Parameters:
0:20 'input' (in 4-component vector of float)
0:? Sequence
0:21 Branch: Return with expression
0:21 add (temp 4-component vector of float)
0:21 add (temp 4-component vector of float)
0:21 add (temp 4-component vector of float)
0:21 'input' (in 4-component vector of float)
0:21 v1: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
0:21 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
0:21 Constant:
0:21 0 (const uint)
0:21 add (temp 4-component vector of float)
0:21 v2: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
0:21 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
0:21 Constant:
0:21 0 (const uint)
0:21 v3: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
0:21 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
0:21 Constant:
0:21 0 (const uint)
0:21 v4: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
0:21 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
0:21 Constant:
0:21 0 (const uint)
0:? Linker Objects
0:? 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
0:? 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
0:? 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
0:? 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 39
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 9
ExecutionMode 4 OriginUpperLeft
Source HLSL 450
Name 4 "PixelShaderFunction"
Name 9 "input"
Name 11 ""
MemberName 11 0 "v1"
Name 13 ""
Name 20 ""
MemberName 20 0 "v2"
Name 22 ""
Name 25 ""
MemberName 25 0 "v3"
MemberName 25 1 "i3"
Name 27 ""
Name 32 ""
MemberName 32 0 "v4"
MemberName 32 1 "i4"
Name 34 ""
MemberDecorate 11 0 Offset 0
Decorate 11 Block
Decorate 13 DescriptorSet 0
MemberDecorate 20 0 Offset 0
Decorate 20 BufferBlock
Decorate 22 DescriptorSet 0
MemberDecorate 25 0 Offset 0
MemberDecorate 25 1 Offset 16
Decorate 25 Block
Decorate 27 DescriptorSet 0
MemberDecorate 32 0 Offset 0
MemberDecorate 32 1 Offset 16
Decorate 32 BufferBlock
Decorate 34 DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Input 7(fvec4)
9(input): 8(ptr) Variable Input
11: TypeStruct 7(fvec4)
12: TypePointer Uniform 11(struct)
13: 12(ptr) Variable Uniform
14: TypeInt 32 1
15: 14(int) Constant 0
16: TypePointer Uniform 7(fvec4)
20: TypeStruct 7(fvec4)
21: TypePointer Uniform 20(struct)
22: 21(ptr) Variable Uniform
25: TypeStruct 7(fvec4) 14(int)
26: TypePointer Uniform 25(struct)
27: 26(ptr) Variable Uniform
32: TypeStruct 7(fvec4) 14(int)
33: TypePointer Uniform 32(struct)
34: 33(ptr) Variable Uniform
4(PixelShaderFunction): 2 Function None 3
5: Label
10: 7(fvec4) Load 9(input)
17: 16(ptr) AccessChain 13 15
18: 7(fvec4) Load 17
19: 7(fvec4) FAdd 10 18
23: 16(ptr) AccessChain 22 15
24: 7(fvec4) Load 23
28: 16(ptr) AccessChain 27 15
29: 7(fvec4) Load 28
30: 7(fvec4) FAdd 24 29
31: 7(fvec4) FAdd 19 30
35: 16(ptr) AccessChain 34 15
36: 7(fvec4) Load 35
37: 7(fvec4) FAdd 31 36
ReturnValue 37
FunctionEnd

22
Test/hlsl.buffer.frag Normal file
View File

@ -0,0 +1,22 @@
cbuffer {
float4 v1;
};
tbuffer {
float4 v2;
};
cbuffer cbufName : register(b2) {
float4 v3;
int i3 : packoffset(c1.y);
};
tbuffer tbufName : register(b8) {
float4 v4 : packoffset(c1);
int i4 : packoffset(c3);
};
float4 PixelShaderFunction(float4 input) : COLOR0
{
return input + v1 + v2 + v3 + v4;
}

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "SPIRV99.1332" #define GLSLANG_REVISION "SPIRV99.1337"
#define GLSLANG_DATE "21-Jul-2016" #define GLSLANG_DATE "25-Jul-2016"

View File

@ -75,6 +75,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.array.frag", "PixelShaderFunction"}, {"hlsl.array.frag", "PixelShaderFunction"},
{"hlsl.assoc.frag", "PixelShaderFunction"}, {"hlsl.assoc.frag", "PixelShaderFunction"},
{"hlsl.attribute.frag", "PixelShaderFunction"}, {"hlsl.attribute.frag", "PixelShaderFunction"},
{"hlsl.buffer.frag", "PixelShaderFunction"},
{"hlsl.cast.frag", "PixelShaderFunction"}, {"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.discard.frag", "PixelShaderFunction"},
{"hlsl.doLoop.frag", "PixelShaderFunction"}, {"hlsl.doLoop.frag", "PixelShaderFunction"},

View File

@ -337,6 +337,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
if (typedefDecl) if (typedefDecl)
parseContext.declareTypedef(idToken.loc, *idToken.string, type, arraySizes); parseContext.declareTypedef(idToken.loc, *idToken.string, type, arraySizes);
else if (type.getBasicType() == EbtBlock)
parseContext.declareBlock(idToken.loc, type, idToken.string);
else { else {
// Declare the variable and add any initializer code to the AST. // Declare the variable and add any initializer code to the AST.
// The top-level node is always made into an aggregate, as that's // The top-level node is always made into an aggregate, as that's
@ -414,10 +416,18 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
TQualifier qualifier; TQualifier qualifier;
qualifier.clear(); qualifier.clear();
acceptQualifier(qualifier); acceptQualifier(qualifier);
TSourceLoc loc = token.loc;
// type_specifier // type_specifier
if (! acceptType(type)) if (! acceptType(type))
return false; return false;
if (type.getBasicType() == EbtBlock) {
// the type was a block, which set some parts of the qualifier
parseContext.mergeQualifiers(loc, type.getQualifier(), qualifier, true);
// further, it can create an anonymous instance of the block
if (peekTokenClass(EHTokSemicolon))
parseContext.declareBlock(loc, type);
} else
type.getQualifier() = qualifier; type.getQualifier() = qualifier;
return true; return true;
@ -825,6 +835,8 @@ bool HlslGrammar::acceptType(TType& type)
break; break;
case EHTokStruct: case EHTokStruct:
case EHTokCBuffer:
case EHTokTBuffer:
return acceptStruct(type); return acceptStruct(type);
break; break;
@ -1186,13 +1198,29 @@ bool HlslGrammar::acceptType(TType& type)
} }
// struct // struct
// : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE // : struct_type IDENTIFIER post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
// | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE // | struct_type post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
//
// struct_type
// : STRUCT
// | CBUFFER
// | TBUFFER
// //
bool HlslGrammar::acceptStruct(TType& type) bool HlslGrammar::acceptStruct(TType& type)
{ {
// This qualifier.storage will tell us whether it's an AST block or
// just a struct.
TQualifier qualifier;
qualifier.clear();
// CBUFFER
if (acceptTokenClass(EHTokCBuffer))
qualifier.storage = EvqUniform;
// TBUFFER
else if (acceptTokenClass(EHTokTBuffer))
qualifier.storage = EvqBuffer;
// STRUCT // STRUCT
if (! acceptTokenClass(EHTokStruct)) else if (! acceptTokenClass(EHTokStruct))
return false; return false;
// IDENTIFIER // IDENTIFIER
@ -1202,6 +1230,9 @@ bool HlslGrammar::acceptStruct(TType& type)
advanceToken(); advanceToken();
} }
// post_decls
acceptPostDecls(type);
// LEFT_BRACE // LEFT_BRACE
if (! acceptTokenClass(EHTokLeftBrace)) { if (! acceptTokenClass(EHTokLeftBrace)) {
expected("{"); expected("{");
@ -1222,11 +1253,15 @@ bool HlslGrammar::acceptStruct(TType& type)
} }
// create the user-defined type // create the user-defined type
if (qualifier.storage == EvqTemporary)
new(&type) TType(typeList, structName); new(&type) TType(typeList, structName);
else
new(&type) TType(typeList, structName, qualifier); // sets EbtBlock
// If it was named, which means it can be reused later, add // If it was named, which means the type can be reused later, add
// it to the symbol table. // it to the symbol table. (Unless it's a block, in which
if (structName.size() > 0) { // case the name is not a type.)
if (type.getBasicType() != EbtBlock && structName.size() > 0) {
TVariable* userTypeDef = new TVariable(&structName, type, true); TVariable* userTypeDef = new TVariable(&structName, type, true);
if (! parseContext.symbolTable.insert(*userTypeDef)) if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error(token.loc, "redefinition", structName.c_str(), "struct"); parseContext.error(token.loc, "redefinition", structName.c_str(), "struct");
@ -2442,6 +2477,7 @@ void HlslGrammar::acceptPostDecls(TType& type)
break; break;
} }
// TODO: process the packoffset information // TODO: process the packoffset information
// c1.y means component y of location slot 1
} else if (! acceptIdentifier(idToken)) { } else if (! acceptIdentifier(idToken)) {
expected("semantic or packoffset or register"); expected("semantic or packoffset or register");
return; return;
@ -2462,6 +2498,7 @@ void HlslGrammar::acceptPostDecls(TType& type)
break; break;
} }
// TODO: process the register information // TODO: process the register information
// b2 means buffer 2
} else { } else {
// semantic, in idToken.string // semantic, in idToken.string
parseContext.handleSemantic(type, *idToken.string); parseContext.handleSemantic(type, *idToken.string);

View File

@ -3898,28 +3898,31 @@ TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TTyp
// //
// Do everything needed to add an interface block. // Do everything needed to add an interface block.
// //
void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TString* instanceName, TArraySizes* arraySizes)
{ {
assert(type.getWritableStruct() != nullptr);
TTypeList& typeList = *type.getWritableStruct();
// fix and check for member storage qualifiers and types that don't belong within a block // fix and check for member storage qualifiers and types that don't belong within a block
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TType& memberType = *typeList[member].type; TType& memberType = *typeList[member].type;
TQualifier& memberQualifier = memberType.getQualifier(); TQualifier& memberQualifier = memberType.getQualifier();
const TSourceLoc& memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
globalQualifierFix(memberLoc, memberQualifier); globalQualifierFix(memberLoc, memberQualifier);
memberQualifier.storage = currentBlockQualifier.storage; memberQualifier.storage = type.getQualifier().storage;
} }
// This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will
// do all the rest. // do all the rest.
if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) { //if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes); // redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
return; // return;
} //}
// Make default block qualification, and adjust the member qualifications // Make default block qualification, and adjust the member qualifications
TQualifier defaultQualification; TQualifier defaultQualification;
switch (currentBlockQualifier.storage) { switch (type.getQualifier().storage) {
case EvqUniform: defaultQualification = globalUniformDefaults; break; case EvqUniform: defaultQualification = globalUniformDefaults; break;
case EvqBuffer: defaultQualification = globalBufferDefaults; break; case EvqBuffer: defaultQualification = globalBufferDefaults; break;
case EvqVaryingIn: defaultQualification = globalInputDefaults; break; case EvqVaryingIn: defaultQualification = globalInputDefaults; break;
@ -3929,12 +3932,12 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
// Special case for "push_constant uniform", which has a default of std430, // Special case for "push_constant uniform", which has a default of std430,
// contrary to normal uniform defaults, and can't have a default tracked for it. // contrary to normal uniform defaults, and can't have a default tracked for it.
if (currentBlockQualifier.layoutPushConstant && ! currentBlockQualifier.hasPacking()) if (type.getQualifier().layoutPushConstant && ! type.getQualifier().hasPacking())
currentBlockQualifier.layoutPacking = ElpStd430; type.getQualifier().layoutPacking = ElpStd430;
// fix and check for member layout qualifiers // fix and check for member layout qualifiers
mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true); mergeObjectLayoutQualifiers(defaultQualification, type.getQualifier(), true);
bool memberWithLocation = false; bool memberWithLocation = false;
bool memberWithoutLocation = false; bool memberWithoutLocation = false;
@ -3958,7 +3961,7 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
if (memberQualifier.hasPacking()) if (memberQualifier.hasPacking())
error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
if (memberQualifier.hasLocation()) { if (memberQualifier.hasLocation()) {
switch (currentBlockQualifier.storage) { switch (type.getQualifier().storage) {
case EvqVaryingIn: case EvqVaryingIn:
case EvqVaryingOut: case EvqVaryingOut:
memberWithLocation = true; memberWithLocation = true;
@ -3979,19 +3982,20 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
} }
// Process the members // Process the members
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); fixBlockLocations(loc, type.getQualifier(), typeList, memberWithLocation, memberWithoutLocation);
fixBlockXfbOffsets(currentBlockQualifier, typeList); fixBlockXfbOffsets(type.getQualifier(), typeList);
fixBlockUniformOffsets(currentBlockQualifier, typeList); fixBlockUniformOffsets(type.getQualifier(), typeList);
// reverse merge, so that currentBlockQualifier now has all layout information // reverse merge, so that currentBlockQualifier now has all layout information
// (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers) // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true); mergeObjectLayoutQualifiers(type.getQualifier(), defaultQualification, true);
// //
// Build and add the interface block as a new type named 'blockName' // Build and add the interface block as a new type named 'blockName'
// //
TType blockType(&typeList, *blockName, currentBlockQualifier); //?? need the block name to be a typename?
TType blockType(&typeList, "" /* *blockName */, type.getQualifier());
if (arraySizes) if (arraySizes)
blockType.newArraySizes(*arraySizes); blockType.newArraySizes(*arraySizes);
@ -4008,20 +4012,20 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
// whose type is EbtBlock, but without all the structure; that will come from the type // whose type is EbtBlock, but without all the structure; that will come from the type
// the instances point to. // the instances point to.
// //
TType blockNameType(EbtBlock, blockType.getQualifier().storage); //??TType blockNameType(EbtBlock, blockType.getQualifier().storage);
TVariable* blockNameVar = new TVariable(blockName, blockNameType); //??TVariable* blockNameVar = new TVariable(blockName, blockNameType);
if (! symbolTable.insert(*blockNameVar)) { //if (! symbolTable.insert(*blockNameVar)) {
TSymbol* existingName = symbolTable.find(*blockName); // TSymbol* existingName = symbolTable.find(*blockName);
if (existingName->getType().getBasicType() == EbtBlock) { // if (existingName->getType().getBasicType() == EbtBlock) {
if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { // if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString()); // error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
return; // return;
} // }
} else { // } else {
error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); // error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
return; // return;
} // }
} //}
// Add the variable, as anonymous or named instanceName. // Add the variable, as anonymous or named instanceName.
// Make an anonymous variable if no name was provided. // Make an anonymous variable if no name was provided.
@ -4031,7 +4035,7 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
TVariable& variable = *new TVariable(instanceName, blockType); TVariable& variable = *new TVariable(instanceName, blockType);
if (! symbolTable.insert(variable)) { if (! symbolTable.insert(variable)) {
if (*instanceName == "") if (*instanceName == "")
error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), ""); error(loc, "nameless block contains a member that already has a name at global scope", "" /* blockName->c_str() */, "");
else else
error(loc, "block instance name redefinition", variable.getName().c_str(), ""); error(loc, "block instance name redefinition", variable.getName().c_str(), "");

View File

@ -133,7 +133,7 @@ public:
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator); TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TQualifier&, TTypeList&); void fixBlockXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(TQualifier&, TTypeList&);
@ -176,8 +176,6 @@ protected:
bool postMainReturn; // if inside a function, true if the function is the entry point and this is after a return statement bool postMainReturn; // if inside a function, true if the function is the entry point and this is after a return statement
const TType* currentFunctionType; // the return type of the function that's currently being parsed const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return bool functionReturnsValue; // true if a non-void function has a return
const TString* blockName;
TQualifier currentBlockQualifier;
TBuiltInResource resources; TBuiltInResource resources;
TLimits& limits; TLimits& limits;

View File

@ -258,6 +258,8 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray; (*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
(*KeywordMap)["struct"] = EHTokStruct; (*KeywordMap)["struct"] = EHTokStruct;
(*KeywordMap)["cbuffer"] = EHTokCBuffer;
(*KeywordMap)["tbuffer"] = EHTokTBuffer;
(*KeywordMap)["typedef"] = EHTokTypedef; (*KeywordMap)["typedef"] = EHTokTypedef;
(*KeywordMap)["true"] = EHTokBoolConstant; (*KeywordMap)["true"] = EHTokBoolConstant;
@ -574,6 +576,9 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
// variable, user type, ... // variable, user type, ...
case EHTokStruct: case EHTokStruct:
case EHTokTypedef: case EHTokTypedef:
case EHTokCBuffer:
case EHTokTBuffer:
return keyword;
case EHTokBoolConstant: case EHTokBoolConstant:
if (strcmp("true", tokenText) == 0) if (strcmp("true", tokenText) == 0)

View File

@ -212,6 +212,8 @@ enum EHlslTokenClass {
EHTokIdentifier, EHTokIdentifier,
EHTokTypeName, EHTokTypeName,
EHTokStruct, EHTokStruct,
EHTokCBuffer,
EHTokTBuffer,
EHTokTypedef, EHTokTypedef,
// constant // constant