diff options
author | Anders Carlsson <andersca@mac.com> | 2011-01-17 03:05:47 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-01-17 03:05:47 +0000 |
commit | 5610490cdfd7bbcbcbd5f166f18093089be8a464 (patch) | |
tree | 76d8e93e5ac4c9b65114c46935756c3fe7d900a9 /clang/lib/Parse/ParseDeclCXX.cpp | |
parent | 7cade2cd2f027e8a85f49fb7d0316e3eb12eba65 (diff) | |
download | bcm5719-llvm-5610490cdfd7bbcbcbd5f166f18093089be8a464.tar.gz bcm5719-llvm-5610490cdfd7bbcbcbd5f166f18093089be8a464.zip |
Change ParseOptionalCXX0XVirtSpecifierSeq to take a VirtSpecifiers struct.
Enforce C++[class.mem]p8:
A virt-specifier-seq shall contain at most one of each virt-specifier.
llvm-svn: 123611
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 960a9fab688..86729878f92 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1268,15 +1268,21 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, /// override /// final /// new -bool Parser::isCXX0XVirtSpecifier() const { +VirtSpecifiers::VirtSpecifier Parser::isCXX0XVirtSpecifier() const { if (Tok.is(tok::kw_new)) - return true; + return VirtSpecifiers::VS_New; - if (Tok.isNot(tok::identifier)) - return false; + if (Tok.is(tok::identifier)) { + IdentifierInfo *II = Tok.getIdentifierInfo(); + + if (II == Ident_override) + return VirtSpecifiers::VS_Override; - const IdentifierInfo *II = Tok.getIdentifierInfo(); - return II == Ident_override || II == Ident_final; + if (II == Ident_final) + return VirtSpecifiers::VS_Final; + } + + return VirtSpecifiers::VS_None; } /// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq. @@ -1284,10 +1290,26 @@ bool Parser::isCXX0XVirtSpecifier() const { /// virt-specifier-seq: /// virt-specifier /// virt-specifier-seq virt-specifier -void Parser::ParseOptionalCXX0XVirtSpecifierSeq() { +void Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) { if (!getLang().CPlusPlus0x) return; + while (true) { + VirtSpecifiers::VirtSpecifier Specifier = isCXX0XVirtSpecifier(); + if (Specifier == VirtSpecifiers::VS_None) + return; + + // C++ [class.mem]p8: + // A virt-specifier-seq shall contain at most one of each virt-specifier. + const char* PrevSpec = 0; + if (VS.SetVirtSpecifier(Specifier, Tok.getLocation(), PrevSpec)) + Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) + << PrevSpec + << FixItHint::CreateRemoval(Tok.getLocation()); + + ConsumeToken(); + } + while (isCXX0XVirtSpecifier()) { // FIXME: Actually do something with the specifier. ConsumeToken(); @@ -1512,7 +1534,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, SkipUntil(tok::comma, true, true); } - ParseOptionalCXX0XVirtSpecifierSeq(); + VirtSpecifiers VS; + ParseOptionalCXX0XVirtSpecifierSeq(VS); // pure-specifier: // '= 0' |