diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-06-08 23:27:34 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-06-08 23:27:34 +0000 |
commit | 290eeb0ec2b6b91f3621e05ef541deb257fbea73 (patch) | |
tree | 7e9a15eeab8ead16e12607e0e360a2d7c4b8ca46 | |
parent | db75ad9c47e8ed60f94e3d555098002fabfe1899 (diff) |
Add more parser support for Microsoft extensions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73101 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Parser.h | 3 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 71 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 3 |
5 files changed, 59 insertions, 28 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 6125fc633d..8eb76a4ef7 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1064,7 +1064,8 @@ private: // EndLoc, if non-NULL, is filled with the location of the last token of // the attribute list. AttributeList *ParseAttributes(SourceLocation *EndLoc = 0); - AttributeList *ParseMicrosoftDeclSpec(); + AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0); + AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0); void ParseTypeofSpecifier(DeclSpec &DS); /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9aab3b9e79..40fbc0ccad 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -209,17 +209,16 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) { /// extended-decl-modifier[opt] /// extended-decl-modifier extended-decl-modifier-seq -AttributeList* Parser::ParseMicrosoftDeclSpec() { +AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) { assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); - AttributeList *CurrAttr = 0; ConsumeToken(); 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)) { + while (Tok.getIdentifierInfo()) { IdentifierInfo *AttrName = Tok.getIdentifierInfo(); SourceLocation AttrNameLoc = ConsumeToken(); if (Tok.is(tok::l_paren)) { @@ -242,8 +241,24 @@ AttributeList* Parser::ParseMicrosoftDeclSpec() { } 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; + return CurrAttr; +} + +AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) { + // Treat these like attributes + // FIXME: Allow Sema to distinguish between these and real attributes! + while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) || + Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___ptr64) || + Tok.is(tok::kw___w64)) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + SourceLocation AttrNameLoc = ConsumeToken(); + if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64)) + // FIXME: Support these properly! + continue; + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, + SourceLocation(), 0, 0, CurrAttr, true); + } + return CurrAttr; } /// ParseDeclaration - Parse a full 'declaration', which consists of @@ -839,22 +854,22 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // Microsoft declspec support. case tok::kw___declspec: - if (!PP.getLangOptions().Microsoft) - goto DoneWithDeclSpec; DS.AddAttributes(ParseMicrosoftDeclSpec()); continue; // Microsoft single token adornments. case tok::kw___forceinline: + // FIXME: Add handling here! + break; + + case tok::kw___ptr64: case tok::kw___w64: case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - if (!PP.getLangOptions().Microsoft) - goto DoneWithDeclSpec; - // Just ignore it. - break; - + DS.AddAttributes(ParseMicrosoftTypeAttributes()); + continue; + // storage-class-specifier case tok::kw_typedef: isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec); @@ -1213,11 +1228,12 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid, ParseTypeofSpecifier(DS); return true; + case tok::kw___ptr64: + case tok::kw___w64: case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - if (!PP.getLangOptions().Microsoft) return false; - ConsumeToken(); + DS.AddAttributes(ParseMicrosoftTypeAttributes()); return true; default: @@ -1671,7 +1687,9 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - return PP.getLangOptions().Microsoft; + case tok::kw___w64: + case tok::kw___ptr64: + return true; } } @@ -1769,7 +1787,10 @@ bool Parser::isDeclarationSpecifier() { case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - return PP.getLangOptions().Microsoft; + case tok::kw___w64: + case tok::kw___ptr64: + case tok::kw___forceinline: + return true; } } @@ -1800,14 +1821,16 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) { isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, getLang())*2; break; + case tok::kw___w64: case tok::kw___ptr64: case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - if (!PP.getLangOptions().Microsoft) - goto DoneWithTypeQuals; - // Just ignore it. - break; + if (AttributesAllowed) { + DS.AddAttributes(ParseMicrosoftTypeAttributes()); + continue; + } + goto DoneWithTypeQuals; case tok::kw___attribute: if (AttributesAllowed) { DS.AddAttributes(ParseAttributes()); @@ -2205,9 +2228,11 @@ void Parser::ParseParenDeclarator(Declarator &D) { RequiresArg = true; } // Eat any Microsoft extensions. - while ((Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) || - (Tok.is(tok::kw___fastcall))) && PP.getLangOptions().Microsoft) - ConsumeToken(); + if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) || + Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) || + Tok.is(tok::kw___ptr64)) { + AttrList = ParseMicrosoftTypeAttributes(AttrList); + } // If we haven't past the identifier yet (or where the identifier would be // stored, if this is an abstract declarator), then this is probably just diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 0e8eebce5c..1e8b18dc2e 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -409,9 +409,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, Attr = ParseAttributes(); // If declspecs exist after tag, parse them. - if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) - // FIXME: Need to do something with the attributes! - ParseMicrosoftDeclSpec(); + if (Tok.is(tok::kw___declspec)) + Attr = ParseMicrosoftDeclSpec(Attr); // Parse the (optional) nested-name-specifier. CXXScopeSpec SS; diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 81696d6a61..f31855b751 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -655,7 +655,10 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw___cdecl: case tok::kw___stdcall: case tok::kw___fastcall: - return PP.getLangOptions().Microsoft ? TPResult::True() : TPResult::False(); + case tok::kw___w64: + case tok::kw___ptr64: + case tok::kw___forceinline: + return TPResult::True(); // The ambiguity resides in a simple-type-specifier/typename-specifier // followed by a '('. The '(' could either be the start of: diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 99b4d77fad..1afdb6011d 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1699,6 +1699,9 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, /// the attribute applies to decls. If the attribute is a type attribute, just /// silently ignore it. static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { + if (Attr.isDeclspecAttribute()) + // FIXME: Try to deal with __declspec attributes! + return; switch (Attr.getKind()) { case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; case AttributeList::AT_address_space: |