Add an explicit derived class of FunctionDecl to model deduction guides rather
than just treating them as FunctionDecls with a funny name.

No functionality change intended.

llvm-svn: 295491
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f7db189..63c10c0 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1599,21 +1599,22 @@
                                          TemplateArgs);
   }
 
-  FunctionDecl *Function =
-      FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
-                           D->getNameInfo(), T, TInfo,
-                           D->getCanonicalDecl()->getStorageClass(),
-                           D->isInlineSpecified(), D->hasWrittenPrototype(),
-                           D->isConstexpr());
-  Function->setRangeEnd(D->getSourceRange().getEnd());
+  FunctionDecl *Function;
+  if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D))
+    Function = CXXDeductionGuideDecl::Create(
+        SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(),
+        D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd());
+  else {
+    Function = FunctionDecl::Create(
+        SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo,
+        D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(),
+        D->hasWrittenPrototype(), D->isConstexpr());
+    Function->setRangeEnd(D->getSourceRange().getEnd());
+  }
 
   if (D->isInlined())
     Function->setImplicitlyInline();
 
-  // A deduction-guide could be explicit.
-  if (D->isExplicitSpecified())
-    Function->setExplicitSpecified();
-
   if (QualifierLoc)
     Function->setQualifierInfo(QualifierLoc);
 
@@ -2781,6 +2782,11 @@
   return VisitFunctionDecl(D, nullptr);
 }
 
+Decl *
+TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+  return VisitFunctionDecl(D, nullptr);
+}
+
 Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
   return VisitCXXMethodDecl(D, nullptr);
 }
@@ -4958,8 +4964,9 @@
         }
         // An implicit deduction guide acts as if it's within the class template
         // specialization described by its name and first N template params.
-        if (FD->isDeductionGuide() && FD->isImplicit()) {
-          TemplateDecl *TD = FD->getDeclName().getCXXDeductionGuideTemplate();
+        auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD);
+        if (Guide && Guide->isImplicit()) {
+          TemplateDecl *TD = Guide->getDeducedTemplate();
           TemplateArgumentListInfo Args(Loc, Loc);
           for (auto Arg : TemplateArgs.getInnermost().take_front(
                                       TD->getTemplateParameters()->size()))