HLSL: Move to correct parsing of annotations, improving all annotations and recent string grammar.
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index 0762514..d458a88 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -721,36 +721,16 @@
     return true;
 }
 
-// string_template_type
-//      : STRING
-//      | STRING identifier LEFT_ANGLE declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE
+// annotations
+//      : LEFT_ANGLE declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE
 //
-bool HlslGrammar::acceptStringTemplateType(TType& type)
+bool HlslGrammar::acceptAnnotations(TQualifier&)
 {
-    // STRING
-    if (! acceptTokenClass(EHTokString))
+    if (! acceptTokenClass(EHTokLeftAngle))
         return false;
 
-    // no matter what happens next, we recognized a string type
-    new(&type) TType(EbtString);
-
-    // identifier LEFT_ANGLE, or not?
-    if (! acceptTokenClass(EHTokIdentifier)) {
-        expected("identifier following 'string'");
-        return false;
-    }
-
-    if (! peekTokenClass(EHTokLeftAngle)) {
-        // then it must be the non-template version, back up and let
-        // normal declaration code handle it
-
-        // recede the identifier
-        recedeToken();
-        return true;
-    }
-
-    // move past the LEFT_ANGLE
-    advanceToken();
+    // note that we are nesting a name space
+    parseContext.nestAnnotations();
 
     // declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE
     do {
@@ -759,15 +739,18 @@
             ;
 
         if (acceptTokenClass(EHTokRightAngle))
-            return true;
+            break;
 
         // declaration
         TIntermNode* node;
         if (! acceptDeclaration(node)) {
-            expected("declaration in string list");
+            expected("declaration in annotation");
             return false;
         }
     } while (true);
+
+    parseContext.unnestAnnotations();
+    return true;
 }
 
 // sampler_type
@@ -942,10 +925,6 @@
         return acceptMatrixTemplateType(type);
         break;
 
-    case EHTokString:
-        return acceptStringTemplateType(type);
-        break;
-
     case EHTokSampler:                // fall through
     case EHTokSampler1d:              // ...
     case EHTokSampler2d:              // ...
@@ -991,6 +970,10 @@
         new(&type) TType(EbtVoid);
         break;
 
+    case EHTokString:
+        new(&type) TType(EbtString);
+        break;
+
     case EHTokFloat:
         new(&type) TType(EbtFloat);
         break;
@@ -2740,16 +2723,9 @@
                 // semantic, in idToken.string
                 parseContext.handleSemantic(idToken.loc, qualifier, *idToken.string);
             }
-        } else if (acceptTokenClass(EHTokLeftAngle)) {
-            // TODO: process annotations, just accepting them for now
-            do {
-                if (peekTokenClass(EHTokNone))
-                    return;
-                if (acceptTokenClass(EHTokRightAngle))
-                    break;
-                advanceToken();
-            } while (true);
-        } else
+        } else if (peekTokenClass(EHTokLeftAngle))
+            acceptAnnotations(qualifier);
+        else
             break;
 
     } while (true);