PR12937: Explicitly deleting an explicit template specialization.

This works around a quirk in the way that explicit template specializations are
handled in Clang. We generate an implicit declaration from the original
template which the explicit specialization is considered to redeclare. This
trips up the explicit delete logic.

This change only works around that strange representation. At some point it'd
be nice to remove those extra declarations to make the AST more accurately
reflect the C++ semantics.

Review by Doug Gregor.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159167 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8280835..dab2d4d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -10316,8 +10316,13 @@
     return;
   }
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
-    Diag(DelLoc, diag::err_deleted_decl_not_first);
-    Diag(Prev->getLocation(), diag::note_previous_declaration);
+    // Don't consider the implicit declaration we generate for explicit
+    // specializations. FIXME: Do not generate these implicit declarations.
+    if (Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization
+        || Prev->getPreviousDecl()) {
+      Diag(DelLoc, diag::err_deleted_decl_not_first);
+      Diag(Prev->getLocation(), diag::note_previous_declaration);
+    }
     // If the declaration wasn't the first, we delete the function anyway for
     // recovery.
   }