diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/AttributeList.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 54 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 3 |
3 files changed, 47 insertions, 14 deletions
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 0170a0671d..3fb6f950ef 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -18,9 +18,9 @@ using namespace clang; AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc, IdentifierInfo *pName, SourceLocation pLoc, ActionBase::ExprTy **ExprList, unsigned numArgs, - AttributeList *n) + AttributeList *n, bool declspec) : AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc), - NumArgs(numArgs), Next(n) { + NumArgs(numArgs), Next(n), DeclspecAttribute(declspec) { if (numArgs == 0) Args = 0; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 39eaf36c95..9aab3b9e79 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -200,18 +200,50 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) { return CurrAttr; } -/// FuzzyParseMicrosoftDeclSpec. When -fms-extensions is enabled, this -/// routine is called to skip/ignore tokens that comprise the MS declspec. -void Parser::FuzzyParseMicrosoftDeclSpec() { +/// ParseMicrosoftDeclSpec - Parse an __declspec construct +/// +/// [MS] decl-specifier: +/// __declspec ( extended-decl-modifier-seq ) +/// +/// [MS] extended-decl-modifier-seq: +/// extended-decl-modifier[opt] +/// extended-decl-modifier extended-decl-modifier-seq + +AttributeList* Parser::ParseMicrosoftDeclSpec() { assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); + + AttributeList *CurrAttr = 0; ConsumeToken(); - if (Tok.is(tok::l_paren)) { - unsigned short savedParenCount = ParenCount; - do { - ConsumeAnyToken(); - } while (ParenCount > savedParenCount && Tok.isNot(tok::eof)); - } - return; + if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, + "declspec")) { + SkipUntil(tok::r_paren, true); // skip until ) or ; + return CurrAttr; + } + while (Tok.is(tok::identifier) || Tok.is(tok::kw_restrict)) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + SourceLocation AttrNameLoc = ConsumeToken(); + if (Tok.is(tok::l_paren)) { + ConsumeParen(); + // FIXME: This doesn't parse __declspec(property(get=get_func_name)) + // correctly. + OwningExprResult ArgExpr(ParseAssignmentExpression()); + if (!ArgExpr.isInvalid()) { + ExprTy* ExprList = ArgExpr.take(); + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, + SourceLocation(), &ExprList, 1, + CurrAttr, true); + } + if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) + SkipUntil(tok::r_paren, false); + } else { + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(), + 0, 0, CurrAttr, true); + } + } + if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) + SkipUntil(tok::r_paren, false); + // FIXME: Return the attributes once we have some Sema support! + return 0; } /// ParseDeclaration - Parse a full 'declaration', which consists of @@ -809,7 +841,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw___declspec: if (!PP.getLangOptions().Microsoft) goto DoneWithDeclSpec; - FuzzyParseMicrosoftDeclSpec(); + DS.AddAttributes(ParseMicrosoftDeclSpec()); continue; // Microsoft single token adornments. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 809dc10c3a..0e8eebce5c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -410,7 +410,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // If declspecs exist after tag, parse them. if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) - FuzzyParseMicrosoftDeclSpec(); + // FIXME: Need to do something with the attributes! + ParseMicrosoftDeclSpec(); // Parse the (optional) nested-name-specifier. CXXScopeSpec SS; |