Add real parsing for __declspec. It doesn't make much of a difference

at the moment because we ignore the result.

llvm-svn: 73056
This commit is contained in:
Eli Friedman 2009-06-08 07:21:15 +00:00
parent 4d38aeb372
commit 06de2b5525
5 changed files with 51 additions and 16 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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;