diff options
-rw-r--r-- | include/clang/Parse/AttributeList.h | 4 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 2 | ||||
-rw-r--r-- | lib/Parse/AttributeList.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 54 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 3 |
5 files changed, 51 insertions, 16 deletions
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 8225c9d33a..26cebf0915 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -38,13 +38,14 @@ class AttributeList { ActionBase::ExprTy **Args; unsigned NumArgs; AttributeList *Next; + bool DeclspecAttribute; AttributeList(const AttributeList &); // DO NOT IMPLEMENT void operator=(const AttributeList &); // DO NOT IMPLEMENT public: AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc, IdentifierInfo *ParmName, SourceLocation ParmLoc, ActionBase::ExprTy **args, unsigned numargs, - AttributeList *Next); + AttributeList *Next, bool declspec = false); ~AttributeList(); enum Kind { // Please keep this list alphabetized. @@ -103,6 +104,7 @@ public: IdentifierInfo *getName() const { return AttrName; } SourceLocation getLoc() const { return AttrLoc; } IdentifierInfo *getParameterName() const { return ParmName; } + bool isDeclspecAttribute() const { return DeclspecAttribute; } Kind getKind() const { return getKind(getName()); } static Kind getKind(const IdentifierInfo *Name); diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 6218ade323..6125fc633d 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1064,7 +1064,7 @@ private: // EndLoc, if non-NULL, is filled with the location of the last token of // the attribute list. AttributeList *ParseAttributes(SourceLocation *EndLoc = 0); - void FuzzyParseMicrosoftDeclSpec(); + AttributeList *ParseMicrosoftDeclSpec(); void ParseTypeofSpecifier(DeclSpec &DS); /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to 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; |