Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 116056)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1399,6 +1399,7 @@
   // EndLoc, if non-NULL, is filled with the location of the last token of
   // the attribute list.
   CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
+  void ParseMicrosoftAttributes();
   AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
   AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
   AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 116056)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -3142,6 +3142,10 @@
       EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
       break;
     }
+	
+    // Skip any Microsoft attributes before a param.
+    if (getLang().Microsoft && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes();
 
     SourceLocation DSStart = Tok.getLocation();
 
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp	(revision 116056)
+++ lib/Parse/ParseDeclCXX.cpp	(working copy)
@@ -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);
   }
 
@@ -1320,6 +1326,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
@@ -2115,3 +2123,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);
+  }
+}
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 116056)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -406,6 +406,9 @@
   CXX0XAttributeList Attr;
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
     Attr = ParseCXX0XAttributes();
+  if (getLang().Microsoft && Tok.is(tok::l_square))
+    ParseMicrosoftAttributes();
+  
   Result = ParseExternalDeclaration(Attr);
   return false;
 }
Index: lib/Parse/ParseTentative.cpp
===================================================================
--- lib/Parse/ParseTentative.cpp	(revision 116056)
+++ lib/Parse/ParseTentative.cpp	(working copy)
@@ -972,6 +972,9 @@
       return TPResult::True(); // '...' is a sign of a function declarator.
     }
 
+    if (getLang().Microsoft && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes();
+
     // decl-specifier-seq
     TPResult TPR = TryParseDeclarationSpecifier();
     if (TPR != TPResult::Ambiguous())
Index: test/Parser/MicrosoftExtensions.c
===================================================================
--- test/Parser/MicrosoftExtensions.c	(revision 116056)
+++ test/Parser/MicrosoftExtensions.c	(working copy)
@@ -78,3 +78,11 @@
    // FIXME, this must not compile
   _uuidof(c);
 }
+
+/* Microsoft attribute tests */
+[repeatable][source_annotation_attribute( Parameter|ReturnValue )]
+struct SA_Post{ SA_Post(); int attr; };
+
+[returnvalue:SA_Post( attr=1)] 
+int foo1([SA_Post(attr=1)] void *param);
+
Index: test/Parser/MicrosoftExtensions.cpp
===================================================================
--- test/Parser/MicrosoftExtensions.cpp	(revision 0)
+++ test/Parser/MicrosoftExtensions.cpp	(revision 0)
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+/* Microsoft attribute tests */
+[repeatable][source_annotation_attribute( Parameter|ReturnValue )]
+struct SA_Post{ SA_Post(); int attr; };
+
+[returnvalue:SA_Post( attr=1)] 
+int foo1([SA_Post(attr=1)] void *param);
+
+namespace {
+  [returnvalue:SA_Post(attr=1)] 
+  int foo2([SA_Post(attr=1)] void *param);
+}
+
+class T {
+  [returnvalue:SA_Post(attr=1)] 
+  int foo3([SA_Post(attr=1)] void *param);
+};
+
+extern "C" {
+  [returnvalue:SA_Post(attr=1)] 
+  int foo5([SA_Post(attr=1)] void *param);
+}
+
+
