aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-06-08 23:27:34 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-06-08 23:27:34 +0000
commit290eeb0ec2b6b91f3621e05ef541deb257fbea73 (patch)
tree7e9a15eeab8ead16e12607e0e360a2d7c4b8ca46
parentdb75ad9c47e8ed60f94e3d555098002fabfe1899 (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.h3
-rw-r--r--lib/Parse/ParseDecl.cpp71
-rw-r--r--lib/Parse/ParseDeclCXX.cpp5
-rw-r--r--lib/Parse/ParseTentative.cpp5
-rw-r--r--lib/Sema/SemaDeclAttr.cpp3
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: