Re-do R131114 without breaking code.

I've edited one diagnostic which would print "copy constructor" for copy
constructors and "constructor" for any other constructor. If anyone is
extremely enamored with this, it can be reinstated with a simple boolean
flag rather than calling getSpecialMember, which is inappropriate.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131143 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c9947ee..332351b 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -600,13 +600,11 @@
   "C++98 requires an accessible copy constructor for class %2 when binding "
   "a reference to a temporary; was %select{private|protected}0">,
   AccessControl, InGroup<BindToTemporaryCopy>;
-def err_access_base : Error<
+def err_access_base_ctor : Error<
   "%select{base class|inherited virtual base class}0 %1 has %select{private|"
-  "protected}3 %select{constructor|copy constructor|copy assignment operator|"
-  "destructor}2">, AccessControl;
-def err_access_field: Error<
-  "field of type %0 has %select{private|protected}2 %select{constructor|copy "
-  "constructor|copy assignment operator|destructor}1">, AccessControl;
+  "protected}2 constructor">, AccessControl;
+def err_access_field_ctor : Error<
+  "field of type %0 has %select{private|protected}1 constructor">, AccessControl;
 
 def err_access_ctor_field :
     Error<"field of type %1 has %select{private|protected}2 constructor">,
@@ -2135,7 +2133,8 @@
 def warn_unavailable_fwdclass_message : Warning<
     "%0 maybe unavailable because receiver type is unknown">;
 def note_unavailable_here : Note<
-  "function has been explicitly marked %select{unavailable|deleted|deprecated}0 here">;
+  "function has been explicitly marked "
+  "%select{unavailable|deleted|deprecated}0 here">;
 def warn_not_enough_argument : Warning<
   "not enough variable arguments in %0 declaration to fit a sentinel">;
 def warn_missing_sentinel : Warning <
@@ -2147,11 +2146,11 @@
   InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
 def err_redefinition : Error<"redefinition of %0">;
 def err_definition_of_implicitly_declared_member : Error<
-  "definition of implicitly declared %select{constructor|copy constructor|"
-  "copy assignment operator|destructor}1">;
+  "definition of implicitly declared %select{default constructor|copy "
+  "constructor|copy assignment operator|destructor}1">;
 def err_definition_of_explicitly_defaulted_member : Error<
-  "definition of explicitly defaulted %select{constructor|copy constructor|"
-  "copy assignment operator|destructor}0">;
+  "definition of explicitly defaulted %select{default constructor|copy "
+  "constructor|copy assignment operator|destructor}0">;
 def err_redefinition_extern_inline : Error<
   "redefinition of a 'extern inline' function %0 is not supported in "
   "%select{C99 mode|C++}1">;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 60b3272..29117f6 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1105,7 +1105,7 @@
 
   enum CXXSpecialMember {
     CXXInvalid = -1,
-    CXXConstructor = 0,
+    CXXDefaultConstructor = 0,
     CXXCopyConstructor = 1,
     CXXCopyAssignment = 2,
     CXXDestructor = 3
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 63983c3..f340bb3 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1423,17 +1423,15 @@
     break;
 
   case InitializedEntity::EK_Base:
-    AccessEntity.setDiag(PDiag(diag::err_access_base)
+    AccessEntity.setDiag(PDiag(diag::err_access_base_ctor)
                           << Entity.isInheritedVirtualBase()
-                          << Entity.getBaseSpecifier()->getType()
-                          << getSpecialMember(Constructor));
+                          << Entity.getBaseSpecifier()->getType());
     break;
 
   case InitializedEntity::EK_Member: {
     const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
-    AccessEntity.setDiag(PDiag(diag::err_access_field)
-                          << Field->getType()
-                          << getSpecialMember(Constructor));
+    AccessEntity.setDiag(PDiag(diag::err_access_field_ctor)
+                          << Field->getType());
     break;
   }
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index e19b06e..b598b46 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1508,15 +1508,18 @@
     if (Ctor->isCopyConstructor())
       return Sema::CXXCopyConstructor;
     
-    return Sema::CXXConstructor;
+    if (Ctor->isDefaultConstructor())
+      return Sema::CXXDefaultConstructor;
   } 
   
   if (isa<CXXDestructorDecl>(MD))
     return Sema::CXXDestructor;
   
-  assert(MD->isCopyAssignmentOperator() && 
-         "Must have copy assignment operator");
-  return Sema::CXXCopyAssignment;
+  if (MD->isCopyAssignmentOperator())
+    return Sema::CXXCopyAssignment;
+
+  llvm_unreachable("getSpecialMember on non-special member");
+  return Sema::CXXInvalid;
 }
 
 /// canRedefineFunction - checks if a function can be redefined. Currently,
@@ -7678,7 +7681,7 @@
       if (!RDecl->hasTrivialCopyConstructor())
         member = CXXCopyConstructor;
       else if (!RDecl->hasTrivialDefaultConstructor())
-        member = CXXConstructor;
+        member = CXXDefaultConstructor;
       else if (!RDecl->hasTrivialCopyAssignment())
         member = CXXCopyAssignment;
       else if (!RDecl->hasTrivialDestructor())
@@ -7707,7 +7710,7 @@
   case CXXInvalid:
     break;
 
-  case CXXConstructor:
+  case CXXDefaultConstructor:
     if (RD->hasUserDeclaredConstructor()) {
       typedef CXXRecordDecl::ctor_iterator ctor_iter;
       for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){
@@ -7781,7 +7784,7 @@
 
   bool (CXXRecordDecl::*hasTrivial)() const;
   switch (member) {
-  case CXXConstructor:
+  case CXXDefaultConstructor:
     hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break;
   case CXXCopyConstructor:
     hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 04d5d4a..47e4ca1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5109,7 +5109,7 @@
   if (SetCtorInitializers(Constructor, 0, 0, /*AnyErrors=*/false) ||
       Trap.hasErrorOccurred()) {
     Diag(CurrentLocation, diag::note_member_synthesized_at) 
-      << CXXConstructor << Context.getTagDeclType(ClassDecl);
+      << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl);
     Constructor->setInvalidDecl();
     return;
   }
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 4228a44..3157b87 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -206,7 +206,7 @@
 
   class Test1 { A a; }; // expected-error {{private member}}
   void test1() {
-    Test1 a;
+    Test1 a; 
     a = Test1(); // expected-note{{implicit default copy}}
   }
 
@@ -224,12 +224,12 @@
     private: A(const A &); // expected-note 2 {{declared private here}}
   };
 
-  class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}}
+  class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private constructor}}
   void test1(const Test1 &t) {
     Test1 a = t; // expected-note{{implicit default copy}}
   }
 
-  class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}}
+  class Test2 : A {}; // expected-error {{base class 'test6::A' has private constructor}}
   void test2(const Test2 &t) {
     Test2 a = t; // expected-note{{implicit default copy}}
   }
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index 5333094..8451739 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 struct A { };
-A::A() { } // expected-error {{definition of implicitly declared constructor}}
+A::A() { } // expected-error {{definition of implicitly declared default constructor}}
 
 struct B { };
 B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}}