Add parsing support for Microsoft attributes. MS attributes will just be skipped and not inserted into the AST for now.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116203 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index e1a97da..c02f41a 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -121,6 +121,8 @@
     CXX0XAttributeList Attr;
     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
       Attr = ParseCXX0XAttributes();
+    if (getLang().Microsoft && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes();
     ParseExternalDeclaration(Attr);
   }
 
@@ -205,6 +207,8 @@
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
     Attr = ParseCXX0XAttributes();
   }
+  if (getLang().Microsoft && Tok.is(tok::l_square))
+    ParseMicrosoftAttributes();
 
   if (Tok.isNot(tok::l_brace)) {
     DS.setExternInLinkageSpec(true);
@@ -224,6 +228,8 @@
     CXX0XAttributeList Attr;
     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
       Attr = ParseCXX0XAttributes();
+    if (getLang().Microsoft && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes();
     ParseExternalDeclaration(Attr);
   }
 
@@ -1321,6 +1327,8 @@
   // Optional C++0x attribute-specifier
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     AttrList = ParseCXX0XAttributes();
+  if (getLang().Microsoft && Tok.is(tok::l_square))
+    ParseMicrosoftAttributes();
 
   if (Tok.is(tok::kw_using)) {
     // FIXME: Check for template aliases
@@ -2116,3 +2124,21 @@
   } else
     return ParseConstantExpression();
 }
+
+/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
+///
+/// [MS] ms-attribute:
+///             '[' token-seq ']'
+///
+/// [MS] ms-attribute-seq:
+///             ms-attribute[opt]
+///             ms-attribute ms-attribute-seq
+void Parser::ParseMicrosoftAttributes() {
+  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
+
+  while (Tok.is(tok::l_square)) {
+    ConsumeBracket();
+    SkipUntil(tok::r_square, true, true);
+    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
+  }
+}