Implement explicit specialization of explicitly-defaulted constructors.
The general out-of-line case (including explicit instantiation mostly
works except that the definition is being lost somewhere between the AST
and CodeGen, so the definition is never emitted.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131933 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index fb34d9f..2481bd0 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2320,6 +2320,9 @@
   Stmt *Pattern = 0;
   if (PatternDecl)
     Pattern = PatternDecl->getBody(PatternDecl);
+  if (!Pattern)
+    // Try to find a defaulted definition
+    PatternDecl->isDefined(PatternDecl);
 
   // Postpone late parsed template instantiations.
   if (PatternDecl && PatternDecl->isLateTemplateParsed() &&
@@ -2337,7 +2340,7 @@
     Pattern = PatternDecl->getBody(PatternDecl);
   }
 
-  if (!Pattern) {
+  if (!Pattern && !PatternDecl->isDefaulted()) {
     if (DefinitionRequired) {
       if (Function->getPrimaryTemplate())
         Diag(PointOfInstantiation, 
@@ -2432,22 +2435,30 @@
   MultiLevelTemplateArgumentList TemplateArgs =
     getTemplateInstantiationArgs(Function, 0, false, PatternDecl);
 
-  // If this is a constructor, instantiate the member initializers.
-  if (const CXXConstructorDecl *Ctor =
-        dyn_cast<CXXConstructorDecl>(PatternDecl)) {
-    InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor,
-                               TemplateArgs);
+  if (PatternDecl->isDefaulted()) {
+    ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true);
+
+    SetDeclDefaulted(Function, PatternDecl->getLocation());
+
+    return;
+  } else {
+    // If this is a constructor, instantiate the member initializers.
+    if (const CXXConstructorDecl *Ctor =
+          dyn_cast<CXXConstructorDecl>(PatternDecl)) {
+      InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor,
+                                 TemplateArgs);
+    }
+
+    // Instantiate the function body.
+    StmtResult Body = SubstStmt(Pattern, TemplateArgs);
+
+    if (Body.isInvalid())
+      Function->setInvalidDecl();
+    
+    ActOnFinishFunctionBody(Function, Body.get(),
+                            /*IsInstantiation=*/true);
   }
 
-  // Instantiate the function body.
-  StmtResult Body = SubstStmt(Pattern, TemplateArgs);
-
-  if (Body.isInvalid())
-    Function->setInvalidDecl();
-  
-  ActOnFinishFunctionBody(Function, Body.get(),
-                          /*IsInstantiation=*/true);
-
   PerformDependentDiagnostics(PatternDecl, TemplateArgs);
 
   savedContext.pop();