// 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);
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();
CXX0XAttributeList Attr;
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
Attr = ParseCXX0XAttributes();
+ if (getLang().Microsoft && Tok.is(tok::l_square))
+ ParseMicrosoftAttributes();
ParseExternalDeclaration(Attr);
}
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
Attr = ParseCXX0XAttributes();
}
+ if (getLang().Microsoft && Tok.is(tok::l_square))
+ ParseMicrosoftAttributes();
if (Tok.isNot(tok::l_brace)) {
DS.setExternInLinkageSpec(true);
CXX0XAttributeList Attr;
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
Attr = ParseCXX0XAttributes();
+ if (getLang().Microsoft && Tok.is(tok::l_square))
+ ParseMicrosoftAttributes();
ParseExternalDeclaration(Attr);
}
// 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
} 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);
+ }
+}
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())
CXX0XAttributeList Attr;
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
Attr = ParseCXX0XAttributes();
+ if (getLang().Microsoft && Tok.is(tok::l_square))
+ ParseMicrosoftAttributes();
+
Result = ParseExternalDeclaration(Attr);
return false;
}
_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);
+
+
void ms_intrinsics(int a)
{
--- /dev/null
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions\r
+\r
+/* Microsoft attribute tests */\r
+[repeatable][source_annotation_attribute( Parameter|ReturnValue )]\r
+struct SA_Post{ SA_Post(); int attr; };\r
+\r
+[returnvalue:SA_Post( attr=1)] \r
+int foo1([SA_Post(attr=1)] void *param);\r
+\r
+namespace {\r
+ [returnvalue:SA_Post(attr=1)] \r
+ int foo2([SA_Post(attr=1)] void *param);\r
+}\r
+\r
+class T {\r
+ [returnvalue:SA_Post(attr=1)] \r
+ int foo3([SA_Post(attr=1)] void *param);\r
+};\r
+\r
+extern "C" {\r
+ [returnvalue:SA_Post(attr=1)] \r
+ int foo5([SA_Post(attr=1)] void *param);\r
+}\r
+\r
+\r