summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-01-17 03:05:47 +0000
committerAnders Carlsson <andersca@mac.com>2011-01-17 03:05:47 +0000
commit5610490cdfd7bbcbcbd5f166f18093089be8a464 (patch)
tree76d8e93e5ac4c9b65114c46935756c3fe7d900a9 /clang/lib/Parse/ParseDeclCXX.cpp
parent7cade2cd2f027e8a85f49fb7d0316e3eb12eba65 (diff)
downloadbcm5719-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.cpp39
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'
OpenPOWER on IntegriCloud