HLSL: cbuffer and tbuffer grammar and production.
authorJohn Kessenich <cepheus@frii.com>
Mon, 25 Jul 2016 22:05:33 +0000 (16:05 -0600)
committerJohn Kessenich <cepheus@frii.com>
Mon, 25 Jul 2016 22:05:33 +0000 (16:05 -0600)
Test/baseResults/hlsl.buffer.frag.out [new file with mode: 0755]
Test/hlsl.buffer.frag [new file with mode: 0644]
glslang/Include/revision.h
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h
hlsl/hlslScanContext.cpp
hlsl/hlslTokens.h

diff --git a/Test/baseResults/hlsl.buffer.frag.out b/Test/baseResults/hlsl.buffer.frag.out
new file mode 100755 (executable)
index 0000000..a145219
--- /dev/null
@@ -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
diff --git a/Test/hlsl.buffer.frag b/Test/hlsl.buffer.frag
new file mode 100644 (file)
index 0000000..fbfdc31
--- /dev/null
@@ -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;
+}
index 8bc17dd..4a4361b 100644 (file)
@@ -2,5 +2,5 @@
 // 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).
 
-#define GLSLANG_REVISION "SPIRV99.1332"
-#define GLSLANG_DATE "21-Jul-2016"
+#define GLSLANG_REVISION "SPIRV99.1337"
+#define GLSLANG_DATE "25-Jul-2016"
index 900aee7..0be8850 100644 (file)
@@ -75,6 +75,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.array.frag", "PixelShaderFunction"},
         {"hlsl.assoc.frag", "PixelShaderFunction"},
         {"hlsl.attribute.frag", "PixelShaderFunction"},
+        {"hlsl.buffer.frag", "PixelShaderFunction"},
         {"hlsl.cast.frag", "PixelShaderFunction"},
         {"hlsl.discard.frag", "PixelShaderFunction"},
         {"hlsl.doLoop.frag", "PixelShaderFunction"},
index fc8360c..37c8635 100755 (executable)
@@ -337,6 +337,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
 
             if (typedefDecl)
                 parseContext.declareTypedef(idToken.loc, *idToken.string, type, arraySizes);
+            else if (type.getBasicType() == EbtBlock)
+                parseContext.declareBlock(idToken.loc, type, idToken.string);
             else {
                 // Declare the variable and add any initializer code to the AST.
                 // The top-level node is always made into an aggregate, as that's
@@ -414,11 +416,19 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
     TQualifier qualifier;
     qualifier.clear();
     acceptQualifier(qualifier);
+    TSourceLoc loc = token.loc;
 
     // type_specifier
     if (! acceptType(type))
         return false;
-    type.getQualifier() = qualifier;
+    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;
 
     return true;
 }
@@ -825,6 +835,8 @@ bool HlslGrammar::acceptType(TType& type)
         break;
 
     case EHTokStruct:
+    case EHTokCBuffer:
+    case EHTokTBuffer:
         return acceptStruct(type);
         break;
 
@@ -1186,13 +1198,29 @@ bool HlslGrammar::acceptType(TType& type)
 }
 
 // struct
-//      : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
-//      | STRUCT            LEFT_BRACE struct_declaration_list RIGHT_BRACE
+//      : struct_type IDENTIFIER post_decls 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)
 {
+    // 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
-    if (! acceptTokenClass(EHTokStruct))
+    else if (! acceptTokenClass(EHTokStruct))
         return false;
 
     // IDENTIFIER
@@ -1202,6 +1230,9 @@ bool HlslGrammar::acceptStruct(TType& type)
         advanceToken();
     }
 
+    // post_decls
+    acceptPostDecls(type);
+
     // LEFT_BRACE
     if (! acceptTokenClass(EHTokLeftBrace)) {
         expected("{");
@@ -1222,11 +1253,15 @@ bool HlslGrammar::acceptStruct(TType& type)
     }
 
     // create the user-defined type
-    new(&type) TType(typeList, structName);
-
-    // If it was named, which means it can be reused later, add
-    // it to the symbol table.
-    if (structName.size() > 0) {
+    if (qualifier.storage == EvqTemporary)
+        new(&type) TType(typeList, structName);
+    else
+        new(&type) TType(typeList, structName, qualifier); // sets EbtBlock
+
+    // If it was named, which means the type can be reused later, add
+    // it to the symbol table.  (Unless it's a block, in which
+    // case the name is not a type.)
+    if (type.getBasicType() != EbtBlock && structName.size() > 0) {
         TVariable* userTypeDef = new TVariable(&structName, type, true);
         if (! parseContext.symbolTable.insert(*userTypeDef))
             parseContext.error(token.loc, "redefinition", structName.c_str(), "struct");
@@ -2442,6 +2477,7 @@ void HlslGrammar::acceptPostDecls(TType& type)
                     break;
                 }
                 // TODO: process the packoffset information
+                // c1.y means component y of location slot 1
             } else if (! acceptIdentifier(idToken)) {
                 expected("semantic or packoffset or register");
                 return;
@@ -2462,6 +2498,7 @@ void HlslGrammar::acceptPostDecls(TType& type)
                     break;
                 }
                 // TODO: process the register information
+                // b2 means buffer 2
             } else {
                 // semantic, in idToken.string
                 parseContext.handleSemantic(type, *idToken.string);
index 83817ea..5b265f1 100755 (executable)
@@ -2533,10 +2533,10 @@ void HlslParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, c
     if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
         dst.storage = src.storage;
     else if ((dst.storage == EvqIn  && src.storage == EvqOut) ||
-        (dst.storage == EvqOut && src.storage == EvqIn))
+             (dst.storage == EvqOut && src.storage == EvqIn))
         dst.storage = EvqInOut;
     else if ((dst.storage == EvqIn    && src.storage == EvqConst) ||
-        (dst.storage == EvqConst && src.storage == EvqIn))
+             (dst.storage == EvqConst && src.storage == EvqIn))
         dst.storage = EvqConstReadOnly;
     else if (src.storage != EvqTemporary && src.storage != EvqGlobal)
         error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
@@ -3898,28 +3898,31 @@ TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TTyp
 //
 // 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
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TType& memberType = *typeList[member].type;
         TQualifier& memberQualifier = memberType.getQualifier();
         const TSourceLoc& memberLoc = typeList[member].loc;
         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
     // do all the rest.
-    if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
-        redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
-        return;
-    }
+    //if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
+    //    redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
+    //    return;
+    //}
 
     // Make default block qualification, and adjust the member qualifications
 
     TQualifier defaultQualification;
-    switch (currentBlockQualifier.storage) {
+    switch (type.getQualifier().storage) {
     case EvqUniform:    defaultQualification = globalUniformDefaults;    break;
     case EvqBuffer:     defaultQualification = globalBufferDefaults;     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,
     // contrary to normal uniform defaults, and can't have a default tracked for it.
-    if (currentBlockQualifier.layoutPushConstant && ! currentBlockQualifier.hasPacking())
-        currentBlockQualifier.layoutPacking = ElpStd430;
+    if (type.getQualifier().layoutPushConstant && ! type.getQualifier().hasPacking())
+        type.getQualifier().layoutPacking = ElpStd430;
 
     // fix and check for member layout qualifiers
 
-    mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
+    mergeObjectLayoutQualifiers(defaultQualification, type.getQualifier(), true);
 
     bool memberWithLocation = false;
     bool memberWithoutLocation = false;
@@ -3958,7 +3961,7 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
         if (memberQualifier.hasPacking())
             error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
         if (memberQualifier.hasLocation()) {
-            switch (currentBlockQualifier.storage) {
+            switch (type.getQualifier().storage) {
             case EvqVaryingIn:
             case EvqVaryingOut:
                 memberWithLocation = true;
@@ -3979,19 +3982,20 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList,
     }
 
     // Process the members
-    fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
-    fixBlockXfbOffsets(currentBlockQualifier, typeList);
-    fixBlockUniformOffsets(currentBlockQualifier, typeList);
+    fixBlockLocations(loc, type.getQualifier(), typeList, memberWithLocation, memberWithoutLocation);
+    fixBlockXfbOffsets(type.getQualifier(), typeList);
+    fixBlockUniformOffsets(type.getQualifier(), typeList);
 
     // reverse merge, so that currentBlockQualifier now has all layout information
     // (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'
     //
 
-    TType blockType(&typeList, *blockName, currentBlockQualifier);
+    //?? need the block name to be a typename?
+    TType blockType(&typeList, "" /* *blockName */, type.getQualifier());
     if (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
     // the instances point to.
     //
-    TType blockNameType(EbtBlock, blockType.getQualifier().storage);
-    TVariable* blockNameVar = new TVariable(blockName, blockNameType);
-    if (! symbolTable.insert(*blockNameVar)) {
-        TSymbol* existingName = symbolTable.find(*blockName);
-        if (existingName->getType().getBasicType() == EbtBlock) {
-            if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
-                error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
-                return;
-            }
-        } else {
-            error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
-            return;
-        }
-    }
+    //??TType blockNameType(EbtBlock, blockType.getQualifier().storage);
+    //??TVariable* blockNameVar = new TVariable(blockName, blockNameType);
+    //if (! symbolTable.insert(*blockNameVar)) {
+    //    TSymbol* existingName = symbolTable.find(*blockName);
+    //    if (existingName->getType().getBasicType() == EbtBlock) {
+    //        if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
+    //            error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
+    //            return;
+    //        }
+    //    } else {
+    //        error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
+    //        return;
+    //    }
+    //}
 
     // Add the variable, as anonymous or named instanceName.
     // 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);
     if (! symbolTable.insert(variable)) {
         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
             error(loc, "block instance name redefinition", variable.getName().c_str(), "");
 
index f128131..9c404ae 100755 (executable)
@@ -133,7 +133,7 @@ public:
     TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
     TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
     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 fixBlockXfbOffsets(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
     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
-    const TString* blockName;
-    TQualifier currentBlockQualifier;
     TBuiltInResource resources;
     TLimits& limits;
 
index 8a4eb73..da39321 100755 (executable)
@@ -258,6 +258,8 @@ void HlslScanContext::fillInKeywordMap()
     (*KeywordMap)["Texture2DMSArray"] =        EHTokTexture2DMSarray;
 
     (*KeywordMap)["struct"] =                  EHTokStruct;
+    (*KeywordMap)["cbuffer"] =                 EHTokCBuffer;
+    (*KeywordMap)["tbuffer"] =                 EHTokTBuffer;
     (*KeywordMap)["typedef"] =                 EHTokTypedef;
 
     (*KeywordMap)["true"] =                    EHTokBoolConstant;
@@ -574,6 +576,9 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
     // variable, user type, ...
     case EHTokStruct:
     case EHTokTypedef:
+    case EHTokCBuffer:
+    case EHTokTBuffer:
+        return keyword;
 
     case EHTokBoolConstant:
         if (strcmp("true", tokenText) == 0)
index 5a5266a..d72b2cd 100755 (executable)
@@ -212,6 +212,8 @@ enum EHlslTokenClass {
     EHTokIdentifier,
     EHTokTypeName,
     EHTokStruct,
+    EHTokCBuffer,
+    EHTokTBuffer,
     EHTokTypedef,
 
     // constant