HLSL: allow keyword-identifiers as cbuffer/struct names.

Issue #791 was partially fixed by PR #1161 (the mat mul implicit
truncations were its main point), but it still wouldn't compile due to
the use of ConstantBuffer as an identifier.  Apparently those fall into
the same class as "float float", where float is both a type and an
identifier.

This allows struct definitions with such keyword-identifiers,
and adds ConstantBuffer to the set.  'cbuffer int' is legal in HLSL,
and 'struct int' appears to only be rejected due to the redefinition
of the 'int' type.

Fixes #791
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index cf0bf05..3c96592 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -2029,10 +2029,18 @@
 
     // Now known to be one of CBUFFER, TBUFFER, CLASS, or STRUCT
 
-    // IDENTIFIER
+
+    // IDENTIFIER.  It might also be a keyword which can double as an identifier.
+    // For example:  'cbuffer ConstantBuffer' or 'struct ConstantBuffer' is legal.
+    // 'cbuffer int' is also legal, and 'struct int' appears rejected only because
+    // it attempts to redefine the 'int' type.
+    const char* idString = getTypeString(peek());
     TString structName = "";
-    if (peekTokenClass(EHTokIdentifier)) {
-        structName = *token.string;
+    if (peekTokenClass(EHTokIdentifier) || idString != nullptr) {
+        if (idString != nullptr)
+            structName = *idString;
+        else
+            structName = *token.string;
         advanceToken();
     }
 
@@ -4056,6 +4064,7 @@
     case EHTokMin10float: return "min10float";
     case EHTokMin16int:   return "min16int";
     case EHTokMin12int:   return "min12int";
+    case EHTokConstantBuffer: return "ConstantBuffer";
     default:
         return nullptr;
     }