aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/AttributeList.h4
-rw-r--r--include/clang/Parse/Parser.h2
-rw-r--r--lib/Parse/AttributeList.cpp4
-rw-r--r--lib/Parse/ParseDecl.cpp54
-rw-r--r--lib/Parse/ParseDeclCXX.cpp3
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;