Generalize the checking for qualification of (non-friend) class
members. Provide a hard error when the qualification doesn't match the
current class type, or a warning + Fix-it if it does match the current
class type. Fixes PR8159.

llvm-svn: 116445
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a34d7ec..1078527 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2265,11 +2265,30 @@
         RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
       return 0;
 
-    if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
-      Diag(D.getIdentifierLoc(),
-           diag::err_member_def_undefined_record)
-        << Name << DC << D.getCXXScopeSpec().getRange();
-      D.setInvalidType();
+    if (isa<CXXRecordDecl>(DC)) {
+      if (!cast<CXXRecordDecl>(DC)->hasDefinition()) {
+        Diag(D.getIdentifierLoc(),
+             diag::err_member_def_undefined_record)
+          << Name << DC << D.getCXXScopeSpec().getRange();
+        D.setInvalidType();
+      } else if (isa<CXXRecordDecl>(CurContext) && 
+                 !D.getDeclSpec().isFriendSpecified()) {
+        // The user provided a superfluous scope specifier inside a class
+        // definition:
+        //
+        // class X {
+        //   void X::f();
+        // };
+        if (CurContext->Equals(DC))
+          Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification)
+            << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
+        else
+          Diag(D.getIdentifierLoc(), diag::err_member_qualification)
+            << Name << D.getCXXScopeSpec().getRange();
+        
+        // Pretend that this qualifier was not here.
+        D.getCXXScopeSpec().clear();
+      }
     }
 
     // Check whether we need to rebuild the type of the given
@@ -3684,18 +3703,6 @@
 
   if (NewFD->isInvalidDecl()) {
     // Ignore all the rest of this.
-
-  } else if (CurContext->isRecord() && D.getCXXScopeSpec().isSet() &&
-             !isFriend) {
-    // The user provided a superfluous scope specifier inside a class
-    // definition:
-    //
-    // class X {
-    //   void X::f();
-    // };
-    Diag(NewFD->getLocation(), diag::warn_member_extra_qualification)
-      << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
-
   } else if (!Redeclaration) {
     // Fake up an access specifier if it's supposed to be a class member.
     if (isa<CXXRecordDecl>(NewFD->getDeclContext()))