HLSL: Attributes: Add [[vk::constant_id()]] and [[vk::push_constant]]
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index db7397c..c71ba16 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -376,11 +376,9 @@
 
     bool forbidDeclarators = (peekTokenClass(EHTokCBuffer) || peekTokenClass(EHTokTBuffer));
     // fully_specified_type
-    if (! acceptFullySpecifiedType(declaredType, nodeList))
+    if (! acceptFullySpecifiedType(declaredType, nodeList, declarator.attributes))
         return false;
 
-    parseContext.transferTypeAttributes(declarator.attributes, declaredType);
-
     // cbuffer and tbuffer end with the closing '}'.
     // No semicolon is included.
     if (forbidDeclarators)
@@ -538,10 +536,11 @@
 bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
 {
     node = nullptr;
+    TAttributeMap attributes;
 
     // fully_specified_type
     TType type;
-    if (! acceptFullySpecifiedType(type))
+    if (! acceptFullySpecifiedType(type, attributes))
         return false;
 
     // filter out type casts
@@ -579,12 +578,12 @@
 //      : type_specifier
 //      | type_qualifier type_specifier
 //
-bool HlslGrammar::acceptFullySpecifiedType(TType& type)
+bool HlslGrammar::acceptFullySpecifiedType(TType& type, const TAttributeMap& attributes)
 {
     TIntermNode* nodeList = nullptr;
-    return acceptFullySpecifiedType(type, nodeList);
+    return acceptFullySpecifiedType(type, nodeList, attributes);
 }
-bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList)
+bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList, const TAttributeMap& attributes)
 {
     // type_qualifier
     TQualifier qualifier;
@@ -603,9 +602,14 @@
 
         return false;
     }
+
     if (type.getBasicType() == EbtBlock) {
         // the type was a block, which set some parts of the qualifier
         parseContext.mergeQualifiers(type.getQualifier(), qualifier);
+    
+        // merge in the attributes
+        parseContext.transferTypeAttributes(attributes, type);
+
         // further, it can create an anonymous instance of the block
         if (peek() != EHTokIdentifier)
             parseContext.declareBlock(loc, type);
@@ -626,7 +630,10 @@
         if (type.isBuiltIn())
             qualifier.builtIn = type.getQualifier().builtIn;
 
-        type.getQualifier()    = qualifier;
+        type.getQualifier() = qualifier;
+
+        // merge in the attributes
+        parseContext.transferTypeAttributes(attributes, type);
     }
 
     return true;
@@ -2333,13 +2340,11 @@
 
         // fully_specified_type
         TType memberType;
-        if (! acceptFullySpecifiedType(memberType, nodeList)) {
+        if (! acceptFullySpecifiedType(memberType, nodeList, attributes)) {
             expected("member type");
             return false;
         }
 
-        parseContext.transferTypeAttributes(attributes, memberType);
-
         // struct_declarator COMMA struct_declarator ...
         bool functionDefinitionAccepted = false;
         do {
@@ -2540,11 +2545,9 @@
 
     // fully_specified_type
     TType* type = new TType;
-    if (! acceptFullySpecifiedType(*type))
+    if (! acceptFullySpecifiedType(*type, attributes))
         return false;
 
-    parseContext.transferTypeAttributes(attributes, *type);
-
     // identifier
     HlslToken idToken;
     acceptIdentifier(idToken);