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 | b971dbdb65149a7cf0c046380186d0204e5b411e (patch) | |
tree | 34252a6fc4d166a18b78501d10761a5e50d833b1 /lib/Parse/ParseDeclCXX.cpp | |
parent | 5be38be82a6631786624625d010d695d529802a8 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123611 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 960a9fab68..86729878f9 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/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' |