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
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 4afdc24..5ead0c5 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -668,3 +668,31 @@
       EndLocation = SymbolLocations[I];
   }
 }
+
+const char *VirtSpecifiers::getSpecifierName(VirtSpecifier VS) {
+  switch (VS) {
+  default: assert(0 && "Unknown specifier");
+  case VS_Override: return "override";
+  case VS_Final: return "final";
+  case VS_New: return "new";
+  }
+}
+
+bool VirtSpecifiers::SetVirtSpecifier(VirtSpecifier VS, SourceLocation Loc,
+                                      const char *&PrevSpec) {
+  if (Specifiers & VS) {
+    PrevSpec = getSpecifierName(VS);
+    return true;
+  }
+
+  Specifiers |= VS;
+
+  switch (VS) {
+  default: assert(0 && "Unknown specifier!");
+  case VS_Override: VS_overrideLoc = Loc; break;
+  case VS_Final:    VS_finalLoc = Loc; break;
+  case VS_New:      VS_newLoc = Loc; break;
+  }
+  return false;
+}
+