Merge remote-tracking branch 'origin/swift-3.1-branch' into stable

* origin/swift-3.1-branch:
  Revert "Revert "[index] Handle properly C++14's template variables.""
  [modules] Do not report missing definitions of demoted constexpr variable templates.
  Reinstate r284008 reverted in r284081, with two fixes:
  [modules] Allow VarDecls with initializers to use special var abbrev.
  Revert accidentally checked in change in r281315.
  Simplify. NFC.
  Add a couple of test files missed in r281258.
  [modules] When we merge two definitions of a function, mark the retained definition as visible in the discarded definition's module, as we do for other kinds of definition.
  PR12298 et al: don't recursively instantiate a template specialization from within the instantiation of that same specialization. This could previously happen for eagerly-instantiated function templates, variable templates, exception specifications, default arguments, and a handful of other cases.
  Fix regression introduced by r279164: only pass definitions as the PatternDef to DiagnoseUninstantiableTemplate, teach hasVisibleDefinition to correctly determine whether a function definition is visible, and mark both the function and the template as visible when merging function template definitions to provide hasVisibleDefinition with the relevant information.
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 77bbdb2..2474637 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -865,6 +865,11 @@
 
     unsigned : NumVarDeclBits;
 
+    // FIXME: We need something similar to CXXRecordDecl::DefinitionData.
+    /// \brief Whether this variable is a definition which was demoted due to
+    /// module merge.
+    unsigned IsThisDeclarationADemotedDefinition : 1;
+
     /// \brief Whether this variable is the exception variable in a C++ catch
     /// or an Objective-C @catch statement.
     unsigned ExceptionVar : 1;
@@ -1198,12 +1203,28 @@
   InitializationStyle getInitStyle() const {
     return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
   }
-
   /// \brief Whether the initializer is a direct-initializer (list or call).
   bool isDirectInit() const {
     return getInitStyle() != CInit;
   }
 
+  /// \brief If this definition should pretend to be a declaration.
+  bool isThisDeclarationADemotedDefinition() const {
+    return isa<ParmVarDecl>(this) ? false :
+      NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
+  }
+
+  /// \brief This is a definition which should be demoted to a declaration.
+  ///
+  /// In some cases (mostly module merging) we can end up with two visible
+  /// definitions one of which needs to be demoted to a declaration to keep
+  /// the AST invariants.
+  void demoteThisDefinitionToDeclaration() {
+    assert (isThisDeclarationADefinition() && "Not a definition!");
+    assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
+    NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
+  }
+
   /// \brief Determine whether this variable is the exception variable in a
   /// C++ catch statememt or an Objective-C \@catch statement.
   bool isExceptionVariable() const {
@@ -1302,6 +1323,10 @@
     NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
   }
 
+  /// \brief Retrieve the variable declaration from which this variable could
+  /// be instantiated, if it is an instantiation (rather than a non-template).
+  VarDecl *getTemplateInstantiationPattern() const;
+
   /// \brief If this variable is an instantiated static data member of a
   /// class template specialization, returns the templated static data member
   /// from which it was instantiated.
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 8671d95..2af95c0 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -43,6 +43,8 @@
 typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
                             TemplateTemplateParmDecl*> TemplateParameter;
 
+NamedDecl *getAsNamedDecl(TemplateParameter P);
+
 /// \brief Stores a list of template parameters for a TemplateDecl and its
 /// derived classes.
 class TemplateParameterList final
@@ -2937,6 +2939,14 @@
   friend class ASTDeclWriter;
 };
 
+inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
+  if (auto *PD = P.dyn_cast<TemplateTypeParmDecl*>())
+    return PD;
+  if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl*>())
+    return PD;
+  return P.get<TemplateTemplateParmDecl*>();
+}
+
 } /* end of namespace clang */
 
 #endif
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index d373e3c..a72bd8e 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7083,6 +7083,10 @@
 def err_in_class_initializer_not_yet_parsed_outer_class
     : Error<"cannot use defaulted default constructor of %0 within "
             "%1 outside of member functions because %2 has an initializer">;
+def err_in_class_initializer_cycle
+    : Error<"default member initializer for %0 uses itself">;
+def err_exception_spec_cycle
+    : Error<"exception specification of %0 uses itself">;
 
 def ext_in_class_initializer_non_constant : Extension<
   "in-class initializer for static data member is not a constant expression; "
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 544af8f..25e8a9d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -18,6 +18,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Availability.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExternalASTSource.h"
@@ -2251,6 +2252,7 @@
   void MergeVarDecl(VarDecl *New, LookupResult &Previous);
   void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
   void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
+  bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
   bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
 
   // AssignmentAction - This is used by all the assignment diagnostic functions
@@ -6691,10 +6693,10 @@
       TemplateInstantiation,
 
       /// We are instantiating a default argument for a template
-      /// parameter. The Entity is the template, and
-      /// TemplateArgs/NumTemplateArguments provides the template
-      /// arguments as specified.
-      /// FIXME: Use a TemplateArgumentList
+      /// parameter. The Entity is the template parameter whose argument is
+      /// being instantiated, the Template is the template, and the
+      /// TemplateArgs/NumTemplateArguments provide the template arguments as
+      /// specified.
       DefaultTemplateArgumentInstantiation,
 
       /// We are instantiating a default argument for a function.
@@ -6809,6 +6811,9 @@
   SmallVector<ActiveTemplateInstantiation, 16>
     ActiveTemplateInstantiations;
 
+  /// Specializations whose definitions are currently being instantiated.
+  llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations;
+
   /// \brief Extra modules inspected when performing a lookup during a template
   /// instantiation. Computed lazily.
   SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
@@ -6915,12 +6920,12 @@
     /// \brief Note that we are instantiating a default argument in a
     /// template-id.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          TemplateDecl *Template,
+                          TemplateParameter Param, TemplateDecl *Template,
                           ArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange = SourceRange());
 
-    /// \brief Note that we are instantiating a default argument in a
-    /// template-id.
+    /// \brief Note that we are substituting either explicitly-specified or
+    /// deduced template arguments during function template argument deduction.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           FunctionTemplateDecl *FunctionTemplate,
                           ArrayRef<TemplateArgument> TemplateArgs,
@@ -6987,9 +6992,14 @@
     /// recursive template instantiations.
     bool isInvalid() const { return Invalid; }
 
+    /// \brief Determine whether we are already instantiating this
+    /// specialization in some surrounding active instantiation.
+    bool isAlreadyInstantiating() const { return AlreadyInstantiating; }
+
   private:
     Sema &SemaRef;
     bool Invalid;
+    bool AlreadyInstantiating;
     bool SavedInNonInstantiationSFINAEContext;
     bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
                                  SourceRange InstantiationRange);
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 943765d..348189b 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1405,6 +1405,10 @@
   /// \brief Make the names within this set of hidden names visible.
   void makeNamesVisible(const HiddenNames &Names, Module *Owner);
 
+  /// \brief Note that MergedDef is a redefinition of the canonical definition
+  /// Def, so Def should be visible whenever MergedDef is.
+  void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef);
+
   /// \brief Take the AST callbacks listener.
   std::unique_ptr<ASTReaderListener> takeListener() {
     return std::move(Listener);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index cfdd557..44564c1 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1926,6 +1926,9 @@
   //
   // FIXME: How do you declare (but not define) a partial specialization of
   // a static data member template outside the containing class?
+  if (isThisDeclarationADemotedDefinition())
+    return DeclarationOnly;
+
   if (isStaticDataMember()) {
     if (isOutOfLine() &&
         !(getCanonicalDecl()->isInline() &&
@@ -2250,6 +2253,56 @@
   return Eval->IsICE;
 }
 
+VarDecl *VarDecl::getTemplateInstantiationPattern() const {
+  // If it's a variable template specialization, find the template or partial
+  // specialization from which it was instantiated.
+  if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(this)) {
+    auto From = VDTemplSpec->getInstantiatedFrom();
+    if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
+      while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) {
+        if (NewVTD->isMemberSpecialization())
+          break;
+        VTD = NewVTD;
+      }
+      return VTD->getTemplatedDecl()->getDefinition();
+    }
+    if (auto *VTPSD =
+            From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+      while (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) {
+        if (NewVTPSD->isMemberSpecialization())
+          break;
+        VTPSD = NewVTPSD;
+      }
+      return VTPSD->getDefinition();
+    }
+  }
+
+  if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+    if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
+      VarDecl *VD = getInstantiatedFromStaticDataMember();
+      while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
+        VD = NewVD;
+      return VD->getDefinition();
+    }
+  }
+
+  if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) {
+
+    while (VarTemplate->getInstantiatedFromMemberTemplate()) {
+      if (VarTemplate->isMemberSpecialization())
+        break;
+      VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
+    }
+
+    assert((!VarTemplate->getTemplatedDecl() ||
+            !isTemplateInstantiation(getTemplateSpecializationKind())) &&
+           "couldn't find pattern for variable instantiation");
+
+    return VarTemplate->getTemplatedDecl();
+  }
+  return nullptr;
+}
+
 VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
   if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
     return cast<VarDecl>(MSI->getInstantiatedFrom());
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index d98d7c0..4126bb6 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -91,6 +91,25 @@
       Info.SubKinds |= (unsigned)SymbolSubKind::TemplateSpecialization;
     }
 
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    Info.Kind = SymbolKind::Variable;
+    if (isa<CXXRecordDecl>(D->getDeclContext())) {
+      Info.Kind = SymbolKind::StaticProperty;
+      Info.Lang = SymbolLanguage::CXX;
+    }
+    if (isa<VarTemplatePartialSpecializationDecl>(D)) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+      Info.SubKinds |= (unsigned)SymbolSubKind::TemplatePartialSpecialization;
+    } else if (isa<VarTemplateSpecializationDecl>(D)) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+      Info.SubKinds |= (unsigned)SymbolSubKind::TemplateSpecialization;
+    } else if (VD->getDescribedVarTemplate()) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+    }
+
   } else {
     switch (D->getKind()) {
     case Decl::Import:
@@ -101,16 +120,6 @@
     case Decl::Function:
       Info.Kind = SymbolKind::Function;
       break;
-    case Decl::ParmVar:
-      Info.Kind = SymbolKind::Variable;
-      break;
-    case Decl::Var:
-      Info.Kind = SymbolKind::Variable;
-      if (isa<CXXRecordDecl>(D->getDeclContext())) {
-        Info.Kind = SymbolKind::StaticProperty;
-        Info.Lang = SymbolLanguage::CXX;
-      }
-      break;
     case Decl::Field:
       Info.Kind = SymbolKind::Field;
       if (const CXXRecordDecl *
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index 21869d8..e623a49 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -130,9 +130,10 @@
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     TKind = SD->getSpecializationKind();
-  }
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     TKind = FD->getTemplateSpecializationKind();
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    TKind = VD->getTemplateSpecializationKind();
   }
   switch (TKind) {
     case TSK_Undeclared:
@@ -164,9 +165,10 @@
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     return SD->getTemplateInstantiationPattern();
-  }
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     return FD->getTemplateInstantiationPattern();
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    return VD->getTemplateInstantiationPattern();
   }
   return nullptr;
 }
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index bec777d..58f61c3 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -286,6 +286,15 @@
 
   VisitDeclContext(D->getDeclContext());
 
+  if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
+    Out << "@VT";
+    VisitTemplateParameterList(VarTmpl->getTemplateParameters());
+  } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
+             = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
+    Out << "@VP";
+    VisitTemplateParameterList(PartialSpec->getTemplateParameters());
+  }
+
   // Variables always have simple names.
   StringRef s = D->getName();
 
@@ -297,6 +306,17 @@
     IgnoreResults = true;
   else
     Out << '@' << s;
+
+  // For a template specialization, mangle the template arguments.
+  if (const VarTemplateSpecializationDecl *Spec
+                              = dyn_cast<VarTemplateSpecializationDecl>(D)) {
+    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    Out << '>';
+    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+      Out << '#';
+      VisitTemplateArgument(Args.get(I));
+    }
+  }
 }
 
 void USRGenerator::VisitNonTypeTemplateParmDecl(
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 1b9ff61..cae1c19 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3667,29 +3667,16 @@
   }
 
   // C++ doesn't have tentative definitions, so go right ahead and check here.
-  VarDecl *Def;
   if (getLangOpts().CPlusPlus &&
-      New->isThisDeclarationADefinition() == VarDecl::Definition &&
-      (Def = Old->getDefinition())) {
-    NamedDecl *Hidden = nullptr;
-    if (!hasVisibleDefinition(Def, &Hidden) &&
-        (New->getFormalLinkage() == InternalLinkage ||
-         New->getDescribedVarTemplate() ||
-         New->getNumTemplateParameterLists() ||
-         New->getDeclContext()->isDependentContext())) {
-      // The previous definition is hidden, and multiple definitions are
-      // permitted (in separate TUs). Form another definition of it.
-    } else if (Old->isStaticDataMember() &&
-               Old->getCanonicalDecl()->isInline() &&
-               Old->getCanonicalDecl()->isConstexpr()) {
+      New->isThisDeclarationADefinition() == VarDecl::Definition) {
+    if (Old->isStaticDataMember() && Old->getCanonicalDecl()->isInline() &&
+        Old->getCanonicalDecl()->isConstexpr()) {
       // This definition won't be a definition any more once it's been merged.
       Diag(New->getLocation(),
            diag::warn_deprecated_redundant_constexpr_static_def);
-    } else {
-      Diag(New->getLocation(), diag::err_redefinition) << New;
-      Diag(Def->getLocation(), diag::note_previous_definition);
-      New->setInvalidDecl();
-      return;
+    } else if (VarDecl *Def = Old->getDefinition()) {
+      if (checkVarDeclRedefinition(Def, New))
+        return;
     }
   }
 
@@ -3718,6 +3705,32 @@
     New->setImplicitlyInline();
 }
 
+/// We've just determined that \p Old and \p New both appear to be definitions
+/// of the same variable. Either diagnose or fix the problem.
+bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
+  if (!hasVisibleDefinition(Old) &&
+      (New->getFormalLinkage() == InternalLinkage ||
+       New->isInline() ||
+       New->getDescribedVarTemplate() ||
+       New->getNumTemplateParameterLists() ||
+       New->getDeclContext()->isDependentContext())) {
+    // The previous definition is hidden, and multiple definitions are
+    // permitted (in separate TUs). Demote this to a declaration.
+    New->demoteThisDefinitionToDeclaration();
+
+    // Make the canonical definition visible.
+    if (auto *OldTD = Old->getDescribedVarTemplate())
+      makeMergedDefinitionVisible(OldTD, New->getLocation());
+    makeMergedDefinitionVisible(Old, New->getLocation());
+    return false;
+  } else {
+    Diag(New->getLocation(), diag::err_redefinition) << New;
+    Diag(Old->getLocation(), diag::note_previous_definition);
+    New->setInvalidDecl();
+    return true;
+  }
+}
+
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
 /// no declarator (e.g. "struct foo;") is parsed.
 Decl *
@@ -9654,24 +9667,15 @@
       VDecl->setInvalidDecl();
   }
 
+  // If adding the initializer will turn this declaration into a definition,
+  // and we already have a definition for this variable, diagnose or otherwise
+  // handle the situation.
   VarDecl *Def;
-  if ((Def = VDecl->getDefinition()) && Def != VDecl) {
-    NamedDecl *Hidden = nullptr;
-    if (!hasVisibleDefinition(Def, &Hidden) &&
-        (VDecl->getFormalLinkage() == InternalLinkage ||
-         VDecl->getDescribedVarTemplate() ||
-         VDecl->getNumTemplateParameterLists() ||
-         VDecl->getDeclContext()->isDependentContext())) {
-      // The previous definition is hidden, and multiple definitions are
-      // permitted (in separate TUs). Form another definition of it.
-    } else {
-      Diag(VDecl->getLocation(), diag::err_redefinition)
-        << VDecl->getDeclName();
-      Diag(Def->getLocation(), diag::note_previous_definition);
-      VDecl->setInvalidDecl();
-      return;
-    }
-  }
+  if ((Def = VDecl->getDefinition()) && Def != VDecl &&
+      (!VDecl->isStaticDataMember() || VDecl->isOutOfLine()) &&
+      !VDecl->isThisDeclarationADemotedDefinition() &&
+      checkVarDeclRedefinition(Def, VDecl))
+    return;
 
   if (getLangOpts().CPlusPlus) {
     // C++ [class.static.data]p4
@@ -10060,7 +10064,11 @@
     // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to
     // the definition of a variable [...] or the declaration of a static data
     // member.
-    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition()) {
+    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition() &&
+        !Var->isThisDeclarationADemotedDefinition()) {
+      assert((!Var->isThisDeclarationADemotedDefinition() ||
+              getLangOpts().Modules) &&
+             "Demoting decls is only in the contest of modules!");
       if (Var->isStaticDataMember()) {
         // C++1z removes the relevant rule; the in-class declaration is always
         // a definition there.
@@ -11283,9 +11291,8 @@
     SkipBody->ShouldSkip = true;
     if (auto *TD = Definition->getDescribedFunctionTemplate())
       makeMergedDefinitionVisible(TD, FD->getLocation());
-    else
-      makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
-                                  FD->getLocation());
+    makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
+                                FD->getLocation());
     return;
   }
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ef46f8f..c66cc3a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4546,6 +4546,11 @@
                                MutiLevelArgList.getInnermost());
     if (Inst.isInvalid())
       return ExprError();
+    if (Inst.isAlreadyInstantiating()) {
+      Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
+      Param->setInvalidDecl();
+      return ExprError();
+    }
 
     ExprResult Result;
     {
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 84d009f..436a19a 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -466,10 +466,14 @@
                                           const NamedDecl *PatternDef,
                                           TemplateSpecializationKind TSK,
                                           bool Complain /*= true*/) {
-  assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation));
+  assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) ||
+         isa<VarDecl>(Instantiation));
 
-  if (PatternDef && (isa<FunctionDecl>(PatternDef)
-                     || !cast<TagDecl>(PatternDef)->isBeingDefined())) {
+  bool IsEntityBeingDefined = false;
+  if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(PatternDef))
+    IsEntityBeingDefined = TD->isBeingDefined();
+
+  if (PatternDef && !IsEntityBeingDefined) {
     NamedDecl *SuggestedDef = nullptr;
     if (!hasVisibleDefinition(const_cast<NamedDecl*>(PatternDef), &SuggestedDef,
                               /*OnlyNeedComplete*/false)) {
@@ -483,33 +487,63 @@
     return false;
   }
 
+  if (!Complain || (PatternDef && PatternDef->isInvalidDecl()))
+    return true;
 
+  llvm::Optional<unsigned> Note;
   QualType InstantiationTy;
   if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
     InstantiationTy = Context.getTypeDeclType(TD);
-  else
-    InstantiationTy = cast<FunctionDecl>(Instantiation)->getType();
-  if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) {
-    // Say nothing
-  } else if (PatternDef) {
+  if (PatternDef) {
     Diag(PointOfInstantiation,
          diag::err_template_instantiate_within_definition)
-      << (TSK != TSK_ImplicitInstantiation)
+      << /*implicit|explicit*/(TSK != TSK_ImplicitInstantiation)
       << InstantiationTy;
     // Not much point in noting the template declaration here, since
     // we're lexically inside it.
     Instantiation->setInvalidDecl();
   } else if (InstantiatedFromMember) {
-    Diag(PointOfInstantiation,
-         diag::err_implicit_instantiate_member_undefined)
-      << InstantiationTy;
-    Diag(Pattern->getLocation(), diag::note_member_declared_at);
+    if (isa<FunctionDecl>(Instantiation)) {
+      Diag(PointOfInstantiation,
+           diag::err_explicit_instantiation_undefined_member)
+        << /*member function*/ 1 << Instantiation->getDeclName()
+        << Instantiation->getDeclContext();
+      Note = diag::note_explicit_instantiation_here;
+    } else {
+      assert(isa<TagDecl>(Instantiation) && "Must be a TagDecl!");
+      Diag(PointOfInstantiation,
+           diag::err_implicit_instantiate_member_undefined)
+        << InstantiationTy;
+      Note = diag::note_member_declared_at;
+    }
   } else {
-    Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
-      << (TSK != TSK_ImplicitInstantiation)
-      << InstantiationTy;
-    Diag(Pattern->getLocation(), diag::note_template_decl_here);
+    if (isa<FunctionDecl>(Instantiation)) {
+      Diag(PointOfInstantiation,
+           diag::err_explicit_instantiation_undefined_func_template)
+        << Pattern;
+      Note = diag::note_explicit_instantiation_here;
+    } else if (isa<TagDecl>(Instantiation)) {
+      Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
+        << (TSK != TSK_ImplicitInstantiation)
+        << InstantiationTy;
+      Note = diag::note_template_decl_here;
+    } else {
+      assert(isa<VarDecl>(Instantiation) && "Must be a VarDecl!");
+      if (isa<VarTemplateSpecializationDecl>(Instantiation)) {
+        Diag(PointOfInstantiation,
+             diag::err_explicit_instantiation_undefined_var_template)
+          << Instantiation;
+        Instantiation->setInvalidDecl();
+      } else
+        Diag(PointOfInstantiation,
+             diag::err_explicit_instantiation_undefined_member)
+          << /*static data member*/ 2 << Instantiation->getDeclName()
+          << Instantiation->getDeclContext();
+      Note = diag::note_explicit_instantiation_here;
+    }
   }
+  if (Note) // Diagnostics were emitted.
+    Diag(Pattern->getLocation(), Note.getValue());
 
   // In general, Instantiation isn't marked invalid to get more than one
   // error for multiple undefined instantiations. But the code that does
@@ -3317,7 +3351,7 @@
   // on the previously-computed template arguments.
   if (ArgType->getType()->isDependentType()) {
     Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
-                                     Template, Converted,
+                                     Param, Template, Converted,
                                      SourceRange(TemplateLoc, RAngleLoc));
     if (Inst.isInvalid())
       return nullptr;
@@ -3369,7 +3403,7 @@
                              NonTypeTemplateParmDecl *Param,
                         SmallVectorImpl<TemplateArgument> &Converted) {
   Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
-                                   Template, Converted,
+                                   Param, Template, Converted,
                                    SourceRange(TemplateLoc, RAngleLoc));
   if (Inst.isInvalid())
     return ExprError();
@@ -3420,8 +3454,9 @@
                              TemplateTemplateParmDecl *Param,
                        SmallVectorImpl<TemplateArgument> &Converted,
                              NestedNameSpecifierLoc &QualifierLoc) {
-  Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted,
-                                   SourceRange(TemplateLoc, RAngleLoc));
+  Sema::InstantiatingTemplate Inst(
+      SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted,
+      SourceRange(TemplateLoc, RAngleLoc));
   if (Inst.isInvalid())
     return TemplateName();
 
@@ -4042,7 +4077,9 @@
     }
 
     // Introduce an instantiation record that describes where we are using
-    // the default template argument.
+    // the default template argument. We're not actually instantiating a
+    // template here, we just create this object to put a note into the
+    // context stack.
     InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param, Converted,
                                SourceRange(TemplateLoc, RAngleLoc));
     if (Inst.isInvalid())
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index e7b221d..8dcd4a0 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -228,6 +228,10 @@
     Inst.NumTemplateArgs = TemplateArgs.size();
     Inst.DeductionInfo = DeductionInfo;
     Inst.InstantiationRange = InstantiationRange;
+    AlreadyInstantiating =
+        !SemaRef.InstantiatingSpecializations
+             .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
+             .second;
     SemaRef.InNonInstantiationSFINAEContext = false;
     SemaRef.ActiveTemplateInstantiations.push_back(Inst);
     if (!Inst.isInstantiationRecord())
@@ -250,13 +254,14 @@
           PointOfInstantiation, InstantiationRange, Entity) {}
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
-    Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
-    ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
+    Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
+    TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
+    SourceRange InstantiationRange)
     : InstantiatingTemplate(
           SemaRef,
           ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation,
-          PointOfInstantiation, InstantiationRange, Template, nullptr,
-          TemplateArgs) {}
+          PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
+          Template, TemplateArgs) {}
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -266,7 +271,11 @@
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
     : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
                             InstantiationRange, FunctionTemplate, nullptr,
-                            TemplateArgs, &DeductionInfo) {}
+                            TemplateArgs, &DeductionInfo) {
+  assert(
+    Kind == ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution ||
+    Kind == ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+}
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -330,7 +339,8 @@
 
 void Sema::InstantiatingTemplate::Clear() {
   if (!Invalid) {
-    if (!SemaRef.ActiveTemplateInstantiations.back().isInstantiationRecord()) {
+    auto &Active = SemaRef.ActiveTemplateInstantiations.back();
+    if (!Active.isInstantiationRecord()) {
       assert(SemaRef.NonInstantiationEntries > 0);
       --SemaRef.NonInstantiationEntries;
     }
@@ -348,6 +358,10 @@
       SemaRef.ActiveTemplateInstantiationLookupModules.pop_back();
     }
 
+    if (!AlreadyInstantiating)
+      SemaRef.InstantiatingSpecializations.erase(
+          std::make_pair(Active.Entity, Active.Kind));
+
     SemaRef.ActiveTemplateInstantiations.pop_back();
     Invalid = true;
   }
@@ -446,7 +460,7 @@
     }
 
     case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
-      TemplateDecl *Template = cast<TemplateDecl>(Active->Entity);
+      TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
       SmallVector<char, 128> TemplateArgsStr;
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       Template->printName(OS);
@@ -1897,6 +1911,7 @@
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
   if (Inst.isInvalid())
     return true;
+  assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller");
   PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
                                       "instantiating class definition");
 
@@ -2122,6 +2137,8 @@
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
   if (Inst.isInvalid())
     return true;
+  if (Inst.isAlreadyInstantiating())
+    return false;
   PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
                                       "instantiating enum definition");
 
@@ -2196,6 +2213,12 @@
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
   if (Inst.isInvalid())
     return true;
+  if (Inst.isAlreadyInstantiating()) {
+    // Error out if we hit an instantiation cycle for this initializer.
+    Diag(PointOfInstantiation, diag::err_in_class_initializer_cycle)
+      << Instantiation;
+    return true;
+  }
   PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
                                       "instantiating default member init");
 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3f4a0f6..2568b6c 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3396,6 +3396,13 @@
     UpdateExceptionSpec(Decl, EST_None);
     return;
   }
+  if (Inst.isAlreadyInstantiating()) {
+    // This exception specification indirectly depends on itself. Reject.
+    // FIXME: Corresponding rule in the standard?
+    Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl;
+    UpdateExceptionSpec(Decl, EST_None);
+    return;
+  }
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -3554,23 +3561,38 @@
   const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();
   assert(PatternDecl && "instantiating a non-template");
 
-  Stmt *Pattern = PatternDecl->getBody(PatternDecl);
-  assert(PatternDecl && "template definition is not a template");
-  if (!Pattern) {
-    // Try to find a defaulted definition
-    PatternDecl->isDefined(PatternDecl);
-  }
-  assert(PatternDecl && "template definition is not a template");
+  const FunctionDecl *PatternDef = PatternDecl->getDefinition();
+  Stmt *Pattern = PatternDef->getBody(PatternDef);
+  if (PatternDef)
+    PatternDecl = PatternDef;
 
   // FIXME: We need to track the instantiation stack in order to know which
   // definitions should be visible within this instantiation.
   if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
                                 Function->getInstantiatedFromMemberFunction(),
-                                     PatternDecl, PatternDecl, TSK,
-                                     /*Complain*/DefinitionRequired))
-     return;
+                                     PatternDecl, PatternDef, TSK,
+                                     /*Complain*/DefinitionRequired)) {
+    if (DefinitionRequired)
+      Function->setInvalidDecl();
+    else if (TSK == TSK_ExplicitInstantiationDefinition) {
+      // Try again at the end of the translation unit (at which point a
+      // definition will be required).
+      assert(!Recursive);
+      PendingInstantiations.push_back(
+        std::make_pair(Function, PointOfInstantiation));
+    } else if (TSK == TSK_ImplicitInstantiation) {
+      if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
+        Diag(PointOfInstantiation, diag::warn_func_template_missing)
+          << Function;
+        Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
+        if (getLangOpts().CPlusPlus11)
+          Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
+            << Function;
+      }
+    }
 
-
+    return;
+  }
 
   // Postpone late parsed template instantiations.
   if (PatternDecl->isLateTemplateParsed() &&
@@ -3604,40 +3626,9 @@
     Pattern = PatternDecl->getBody(PatternDecl);
   }
 
-  // FIXME: Check if we could sink these diagnostics in
-  // DiagnoseUninstantiableTemplate.
-  if (!Pattern && !PatternDecl->isDefaulted()) {
-    if (DefinitionRequired) {
-      if (Function->getPrimaryTemplate())
-        Diag(PointOfInstantiation,
-             diag::err_explicit_instantiation_undefined_func_template)
-          << Function->getPrimaryTemplate();
-      else
-        Diag(PointOfInstantiation,
-             diag::err_explicit_instantiation_undefined_member)
-          << 1 << Function->getDeclName() << Function->getDeclContext();
-
-      if (PatternDecl)
-        Diag(PatternDecl->getLocation(),
-             diag::note_explicit_instantiation_here);
-      Function->setInvalidDecl();
-    } else if (TSK == TSK_ExplicitInstantiationDefinition) {
-      assert(!Recursive);
-      PendingInstantiations.push_back(
-        std::make_pair(Function, PointOfInstantiation));
-    } else if (TSK == TSK_ImplicitInstantiation) {
-      if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
-        Diag(PointOfInstantiation, diag::warn_func_template_missing)
-          << Function;
-        Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
-        if (getLangOpts().CPlusPlus11)
-          Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
-            << Function;
-      }
-    }
-
-    return;
-  }
+  // Note, we should never try to instantiate a deleted function template.
+  assert((Pattern || PatternDecl->isDefaulted()) &&
+         "unexpected kind of function template definition");
 
   // C++1y [temp.explicit]p10:
   //   Except for inline functions, declarations with types deduced from their
@@ -3661,7 +3652,7 @@
   }
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
-  if (Inst.isInvalid())
+  if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
     return;
   PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
                                       "instantiating function definition");
@@ -3928,10 +3919,6 @@
   else if (OldVar->isInline())
     Var->setImplicitlyInline();
 
-  if (Var->getAnyInitializer())
-    // We already have an initializer in the class.
-    return;
-
   if (OldVar->getInit()) {
     if (Var->isStaticDataMember() && !OldVar->isOutOfLine())
       PushExpressionEvaluationContext(Sema::ConstantEvaluated, OldVar);
@@ -3967,9 +3954,23 @@
     }
 
     PopExpressionEvaluationContext();
-  } else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) &&
-             !Var->isCXXForRangeDecl())
+  } else {
+    if (Var->isStaticDataMember()) {
+      if (!Var->isOutOfLine())
+        return;
+
+      // If the declaration inside the class had an initializer, don't add
+      // another one to the out-of-line definition.
+      if (OldVar->getFirstDecl()->hasInit())
+        return;
+    }
+
+    // We'll add an initializer to a for-range declaration later.
+    if (Var->isCXXForRangeDecl())
+      return;
+
     ActOnUninitializedDecl(Var, false);
+  }
 }
 
 /// \brief Instantiate the definition of the given variable from its
@@ -4059,11 +4060,15 @@
       // FIXME: Factor out the duplicated instantiation context setup/tear down
       // code here.
       InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
-      if (Inst.isInvalid())
+      if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
         return;
       PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(),
                                           "instantiating variable initializer");
 
+      // The instantiation is visible here, even if it was first declared in an
+      // unimported module.
+      Var->setHidden(false);
+
       // If we're performing recursive template instantiation, create our own
       // queue of pending implicit instantiations that we will instantiate
       // later, while we're still within our own instantiation context.
@@ -4112,33 +4117,17 @@
     Def = PatternDecl->getDefinition();
   }
 
-  // FIXME: Check that the definition is visible before trying to instantiate
-  // it. This requires us to track the instantiation stack in order to know
-  // which definitions should be visible.
+  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
 
   // If we don't have a definition of the variable template, we won't perform
   // any instantiation. Rather, we rely on the user to instantiate this
   // definition (or provide a specialization for it) in another translation
   // unit.
-  if (!Def) {
-    if (DefinitionRequired) {
-      if (VarSpec)
-        Diag(PointOfInstantiation,
-             diag::err_explicit_instantiation_undefined_var_template) << Var;
-      else
-        Diag(PointOfInstantiation,
-             diag::err_explicit_instantiation_undefined_member)
-            << 2 << Var->getDeclName() << Var->getDeclContext();
-      Diag(PatternDecl->getLocation(),
-           diag::note_explicit_instantiation_here);
-      if (VarSpec)
-        Var->setInvalidDecl();
-    } else if (Var->getTemplateSpecializationKind()
-                 == TSK_ExplicitInstantiationDefinition) {
+  if (!Def && !DefinitionRequired) {
+    if (TSK == TSK_ExplicitInstantiationDefinition) {
       PendingInstantiations.push_back(
         std::make_pair(Var, PointOfInstantiation));
-    } else if (Var->getTemplateSpecializationKind()
-                 == TSK_ImplicitInstantiation) {
+    } else if (TSK == TSK_ImplicitInstantiation) {
       // Warn about missing definition at the end of translation unit.
       if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
         Diag(PointOfInstantiation, diag::warn_var_template_missing)
@@ -4147,12 +4136,20 @@
         if (getLangOpts().CPlusPlus11)
           Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var;
       }
+      return;
     }
 
-    return;
   }
 
-  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
+  // FIXME: We need to track the instantiation stack in order to know which
+  // definitions should be visible within this instantiation.
+  // FIXME: Produce diagnostics when Var->getInstantiatedFromStaticDataMember().
+  if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Var,
+                                     /*InstantiatedFromMember*/false,
+                                     PatternDecl, Def, TSK,
+                                     /*Complain*/DefinitionRequired))
+    return;
+
 
   // Never instantiate an explicit specialization.
   if (TSK == TSK_ExplicitSpecialization)
@@ -4188,7 +4185,7 @@
   }
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
-  if (Inst.isInvalid())
+  if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
     return;
   PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(),
                                       "instantiating variable definition");
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index ef71b0a..f173510 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -6890,6 +6890,14 @@
       return false;
     }
     D = ED->getDefinition();
+  } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+    if (auto *Pattern = FD->getTemplateInstantiationPattern())
+      FD = Pattern;
+    D = FD->getDefinition();
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    if (auto *Pattern = VD->getTemplateInstantiationPattern())
+      VD = Pattern;
+    D = VD->getDefinition();
   }
   assert(D && "missing definition for pattern of instantiated definition");
 
@@ -6897,7 +6905,7 @@
   if (isVisible(D))
     return true;
 
-  // The external source may have additional definitions of this type that are
+  // The external source may have additional definitions of this entity that are
   // visible, so complete the redeclaration chain now and ask again.
   if (auto *Source = Context.getExternalSource()) {
     Source->CompleteRedeclChain(D);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 325b379..f526738 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3416,6 +3416,31 @@
   }
 }
 
+/// We've merged the definition \p MergedDef into the existing definition
+/// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made
+/// visible.
+void ASTReader::mergeDefinitionVisibility(NamedDecl *Def,
+                                          NamedDecl *MergedDef) {
+  // FIXME: This doesn't correctly handle the case where MergedDef is visible
+  // in modules other than its owning module. We should instead give the
+  // ASTContext a list of merged definitions for Def.
+  if (Def->isHidden()) {
+    // If MergedDef is visible or becomes visible, make the definition visible.
+    if (!MergedDef->isHidden())
+      Def->Hidden = false;
+    else if (getContext().getLangOpts().ModulesLocalVisibility) {
+      getContext().mergeDefinitionIntoModule(
+          Def, MergedDef->getImportedOwningModule(),
+          /*NotifyListeners*/ false);
+      PendingMergedDefinitionsToDeduplicate.insert(Def);
+    } else {
+      auto SubmoduleID = MergedDef->getOwningModuleID();
+      assert(SubmoduleID && "hidden definition in no module");
+      HiddenNamesMap[getSubmodule(SubmoduleID)].push_back(Def);
+    }
+  }
+}
+
 bool ASTReader::loadGlobalIndex() {
   if (GlobalIndex)
     return false;
@@ -8491,8 +8516,11 @@
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
       // FIXME: Check for =delete/=default?
       // FIXME: Complain about ODR violations here?
-      if (!getContext().getLangOpts().Modules || !FD->hasBody())
+      const FunctionDecl *Defn = nullptr;
+      if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn))
         FD->setLazyBody(PB->second);
+      else
+        mergeDefinitionVisibility(const_cast<FunctionDecl*>(Defn), FD);
       continue;
     }
 
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 7f9ad96..3039149 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -382,27 +382,6 @@
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
-
-    /// We've merged the definition \p MergedDef into the existing definition
-    /// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made
-    /// visible.
-    void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef) {
-      if (Def->isHidden()) {
-        // If MergedDef is visible or becomes visible, make the definition visible.
-        if (!MergedDef->isHidden())
-          Def->Hidden = false;
-        else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
-          Reader.getContext().mergeDefinitionIntoModule(
-              Def, MergedDef->getImportedOwningModule(),
-              /*NotifyListeners*/ false);
-          Reader.PendingMergedDefinitionsToDeduplicate.insert(Def);
-        } else {
-          auto SubmoduleID = MergedDef->getOwningModuleID();
-          assert(SubmoduleID && "hidden definition in no module");
-          Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(Def);
-        }
-      }
-    }
   };
 } // end namespace clang
 
@@ -709,7 +688,7 @@
     if (OldDef) {
       Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
       ED->IsCompleteDefinition = false;
-      mergeDefinitionVisibility(OldDef, ED);
+      Reader.mergeDefinitionVisibility(OldDef, ED);
     } else {
       OldDef = ED;
     }
@@ -1236,6 +1215,7 @@
   VD->VarDeclBits.TSCSpec = Record[Idx++];
   VD->VarDeclBits.InitStyle = Record[Idx++];
   if (!isa<ParmVarDecl>(VD)) {
+    VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record[Idx++];
     VD->NonParmVarDeclBits.ExceptionVar = Record[Idx++];
     VD->NonParmVarDeclBits.NRVOVariable = Record[Idx++];
     VD->NonParmVarDeclBits.CXXForRangeDecl = Record[Idx++];
@@ -1256,7 +1236,7 @@
 
   if (uint64_t Val = Record[Idx++]) {
     VD->setInit(Reader.ReadExpr(F));
-    if (Val > 1) {
+    if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
       EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
       Eval->CheckedICE = true;
       Eval->IsICE = Val == 3;
@@ -1597,7 +1577,7 @@
                                                     DD.Definition));
     Reader.PendingDefinitions.erase(MergeDD.Definition);
     MergeDD.Definition->IsCompleteDefinition = false;
-    mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
+    Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
     assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
            "already loaded pending lookups for merged definition");
   }
@@ -3083,6 +3063,29 @@
 namespace clang {
 template<>
 void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
+                                           Redeclarable<VarDecl> *D,
+                                           Decl *Previous, Decl *Canon) {
+  VarDecl *VD = static_cast<VarDecl*>(D);
+  VarDecl *PrevVD = cast<VarDecl>(Previous);
+  D->RedeclLink.setPrevious(PrevVD);
+  D->First = PrevVD->First;
+
+  // We should keep at most one definition on the chain.
+  // FIXME: Cache the definition once we've found it. Building a chain with
+  // N definitions currently takes O(N^2) time here.
+  if (VD->isThisDeclarationADefinition() == VarDecl::Definition) {
+    for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) {
+      if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) {
+        Reader.mergeDefinitionVisibility(CurD, VD);
+        VD->demoteThisDefinitionToDeclaration();
+        break;
+      }
+    }
+  }
+}
+
+template<>
+void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                            Redeclarable<FunctionDecl> *D,
                                            Decl *Previous, Decl *Canon) {
   FunctionDecl *FD = static_cast<FunctionDecl*>(D);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 158123b..7b12bf0 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -893,6 +893,7 @@
   Record.push_back(D->getTSCSpec());
   Record.push_back(D->getInitStyle());
   if (!isa<ParmVarDecl>(D)) {
+    Record.push_back(D->isThisDeclarationADemotedDefinition());
     Record.push_back(D->isExceptionVariable());
     Record.push_back(D->isNRVOVariable());
     Record.push_back(D->isCXXForRangeDecl());
@@ -941,8 +942,6 @@
       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
       !D->hasExtInfo() &&
       D->getFirstDecl() == D->getMostRecentDecl() &&
-      D->getInitStyle() == VarDecl::CInit &&
-      D->getInit() == nullptr &&
       D->getKind() == Decl::Var &&
       !D->isInline() &&
       !D->isConstexpr() &&
@@ -999,6 +998,8 @@
   // Check things we know are true of *every* PARM_VAR_DECL, which is more than
   // just us assuming it.
   assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
+  assert(!D->isThisDeclarationADemotedDefinition()
+         && "PARM_VAR_DECL can't be demoted definition.");
   assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
   assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
   assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
@@ -1873,9 +1874,9 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
   // VarDecl
-  Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass
-  Abv->Add(BitCodeAbbrevOp(0));                       // getTSCSpec
-  Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer
+  Abv->Add(BitCodeAbbrevOp(0));                       // SClass
+  Abv->Add(BitCodeAbbrevOp(0));                       // TSCSpec
+  Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
   Abv->Add(BitCodeAbbrevOp(0));                       // Linkage
   Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
   Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
@@ -1949,9 +1950,10 @@
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
   // VarDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getTSCSpec
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
@@ -1962,8 +1964,8 @@
   Abv->Add(BitCodeAbbrevOp(0));                         // isInitCapture
   Abv->Add(BitCodeAbbrevOp(0));                         // isPrevDeclInSameScope
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasInit
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasMemberSpecInfo
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // IsInitICE (local)
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum)
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 61b9675..7db5d53 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -1,4 +1,4 @@
-// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
 
 template <typename TemplArg>
 class TemplCls {
@@ -29,3 +29,14 @@
 // CHECK: [[@LINE+2]]:7 | function/C | operator new | c:@F@operator new#l# | __Znwm |
 // CHECK: [[@LINE+1]]:20 | type-alias/C | size_t | {{.*}} | Ref |
 void* operator new(size_t sz);
+
+// CHECK: [[@LINE+1]]:37 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Def | rel: 0
+template<typename T> static const T tmplVar = T(0);
+// CHECK: [[@LINE+1]]:29 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Def | rel: 0
+template<> static const int tmplVar<int> = 0;
+// CHECK: [[@LINE+2]]:5 | variable/C | gvi | c:@gvi | _gvi | Def | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Ref,Read | rel: 0
+int gvi = tmplVar<int>;
+// CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read | rel: 0
+int gvf = tmplVar<float>;
diff --git a/test/Modules/Inputs/PR28752/Subdir1/b.h b/test/Modules/Inputs/PR28752/Subdir1/b.h
new file mode 100644
index 0000000..4d8de21
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/Subdir1/b.h
@@ -0,0 +1,4 @@
+#include <vector>
+
+template<typename T> struct A { static bool b; };
+template<typename T> bool A<T>::b;
diff --git a/test/Modules/Inputs/PR28752/Subdir1/c.h b/test/Modules/Inputs/PR28752/Subdir1/c.h
new file mode 100644
index 0000000..38822fb
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/Subdir1/c.h
@@ -0,0 +1,2 @@
+template<typename T> struct A { static bool b; };
+template<typename T> bool A<T>::b;
diff --git a/test/Modules/Inputs/PR28752/Subdir1/module.modulemap b/test/Modules/Inputs/PR28752/Subdir1/module.modulemap
new file mode 100644
index 0000000..8d3bfe9
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/Subdir1/module.modulemap
@@ -0,0 +1,5 @@
+module b {
+  module "b.h" { header "b.h" export * }
+  module "c.h" { header "c.h" export * }
+  export *
+}
diff --git a/test/Modules/Inputs/PR28752/a.h b/test/Modules/Inputs/PR28752/a.h
new file mode 100644
index 0000000..3b3a25f
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/a.h
@@ -0,0 +1 @@
+#include <vector>
diff --git a/test/Modules/Inputs/PR28752/module.modulemap b/test/Modules/Inputs/PR28752/module.modulemap
new file mode 100644
index 0000000..caf888f
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/module.modulemap
@@ -0,0 +1 @@
+module a { header "a.h" export * }
diff --git a/test/Modules/Inputs/PR28752/vector b/test/Modules/Inputs/PR28752/vector
new file mode 100644
index 0000000..fc5dafa
--- /dev/null
+++ b/test/Modules/Inputs/PR28752/vector
@@ -0,0 +1,28 @@
+#ifndef VECTOR
+#define VECTOR
+template <bool, typename> struct B;
+template <typename _Tp> struct B<true, _Tp> { typedef _Tp type; };
+namespace std {
+template <typename> struct D {
+
+  template <typename _Alloc2> struct F {
+    static const bool value = 0;
+  };
+
+  template <typename _Alloc2>
+  typename B<F<_Alloc2>::value, _Alloc2>::type _S_select(_Alloc2);
+  template <typename _Alloc2>
+  static
+  typename B<!F<_Alloc2>::value, _Alloc2>::type _S_select(_Alloc2);
+};
+template <typename _Alloc>
+template <typename _Alloc2>
+const bool D<_Alloc>::F<_Alloc2>::value;
+
+template <typename> class vector {
+public:
+  vector(int);
+  vector(vector &) : vector(D<bool>::_S_select((bool)0)) {}
+};
+}
+#endif // VECTOR
\ No newline at end of file
diff --git a/test/Modules/Inputs/merge-template-pattern-visibility/a.h b/test/Modules/Inputs/merge-template-pattern-visibility/a.h
index 7f9b649..e659202 100644
--- a/test/Modules/Inputs/merge-template-pattern-visibility/a.h
+++ b/test/Modules/Inputs/merge-template-pattern-visibility/a.h
@@ -3,3 +3,4 @@
 
 template<typename, typename> struct A {};
 template<typename T> struct B : A<T> {};
+template<typename T> inline auto C(T) {}
diff --git a/test/Modules/Inputs/merge-template-pattern-visibility/b.h b/test/Modules/Inputs/merge-template-pattern-visibility/b.h
index 5ed18e7..41b52d5 100644
--- a/test/Modules/Inputs/merge-template-pattern-visibility/b.h
+++ b/test/Modules/Inputs/merge-template-pattern-visibility/b.h
@@ -3,7 +3,18 @@
 
 template<typename, typename> struct A {};
 template<typename T> struct B : A<T> {};
+template<typename T> inline auto C(T) {}
 
 inline void f() {
   B<int> bi;
+  C(0);
+}
+
+namespace CrossModuleMerge {
+  template<typename, typename = int> struct A;
+  template<typename T> struct B;
+
+  template<typename, typename> struct A {};
+  template<typename T> struct B : A<T> {};
+  template<typename T> inline auto C(T) {}
 }
diff --git a/test/Modules/Inputs/merge-template-pattern-visibility/c.h b/test/Modules/Inputs/merge-template-pattern-visibility/c.h
new file mode 100644
index 0000000..db80eda
--- /dev/null
+++ b/test/Modules/Inputs/merge-template-pattern-visibility/c.h
@@ -0,0 +1,9 @@
+namespace CrossModuleMerge {
+  template<typename, typename = int> struct A;
+  template<typename T> struct B;
+
+  template<typename, typename> struct A {};
+  template<typename T> struct B : A<T> {};
+  template<typename T> inline auto C(T) {}
+}
+
diff --git a/test/Modules/Inputs/merge-template-pattern-visibility/d.h b/test/Modules/Inputs/merge-template-pattern-visibility/d.h
new file mode 100644
index 0000000..464f0f5
--- /dev/null
+++ b/test/Modules/Inputs/merge-template-pattern-visibility/d.h
@@ -0,0 +1 @@
+// d.h: empty
diff --git a/test/Modules/Inputs/merge-template-pattern-visibility/module.modulemap b/test/Modules/Inputs/merge-template-pattern-visibility/module.modulemap
index ba97abb..e00d1b9 100644
--- a/test/Modules/Inputs/merge-template-pattern-visibility/module.modulemap
+++ b/test/Modules/Inputs/merge-template-pattern-visibility/module.modulemap
@@ -2,3 +2,7 @@
   module A { header "a.h" }
   module B { header "b.h" }
 }
+module Y {
+  module C { header "c.h" }
+  module D { header "d.h" }
+}
diff --git a/test/Modules/Inputs/merge-var-template-def/a.h b/test/Modules/Inputs/merge-var-template-def/a.h
new file mode 100644
index 0000000..6b414b3
--- /dev/null
+++ b/test/Modules/Inputs/merge-var-template-def/a.h
@@ -0,0 +1,8 @@
+#ifndef A_H
+#define A_H
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#endif
diff --git a/test/Modules/Inputs/merge-var-template-def/b1.h b/test/Modules/Inputs/merge-var-template-def/b1.h
new file mode 100644
index 0000000..35cab9d
--- /dev/null
+++ b/test/Modules/Inputs/merge-var-template-def/b1.h
@@ -0,0 +1,9 @@
+#ifndef B1_H
+#define B1_H
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#include "a.h"
+#endif
diff --git a/test/Modules/Inputs/merge-var-template-def/b2.h b/test/Modules/Inputs/merge-var-template-def/b2.h
new file mode 100644
index 0000000..6ab87c2
--- /dev/null
+++ b/test/Modules/Inputs/merge-var-template-def/b2.h
@@ -0,0 +1,9 @@
+#ifndef B2_H
+#define B2_H
+
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#endif
diff --git a/test/Modules/Inputs/merge-var-template-def/module.modulemap b/test/Modules/Inputs/merge-var-template-def/module.modulemap
new file mode 100644
index 0000000..b2c96bd
--- /dev/null
+++ b/test/Modules/Inputs/merge-var-template-def/module.modulemap
@@ -0,0 +1,5 @@
+module a { header "a.h" export * }
+module b {
+  module b1 { header "b1.h" export * }
+  module b2 { header "b2.h" export * }
+}
diff --git a/test/Modules/merge-template-pattern-visibility.cpp b/test/Modules/merge-template-pattern-visibility.cpp
index db759b5..ec5aa26 100644
--- a/test/Modules/merge-template-pattern-visibility.cpp
+++ b/test/Modules/merge-template-pattern-visibility.cpp
@@ -1,4 +1,18 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fno-modules-error-recovery \
+// RUN: %clang_cc1 -fmodules -fno-modules-error-recovery -std=c++14 \
 // RUN:            -fmodule-name=X -emit-module %S/Inputs/merge-template-pattern-visibility/module.modulemap -x c++ \
-// RUN:            -fmodules-local-submodule-visibility
+// RUN:            -fmodules-local-submodule-visibility -o %t/X.pcm
+// RUN: %clang_cc1 -fmodules -fno-modules-error-recovery -std=c++14 \
+// RUN:            -fmodule-name=Y -emit-module %S/Inputs/merge-template-pattern-visibility/module.modulemap -x c++ \
+// RUN:            -fmodules-local-submodule-visibility -o %t/Y.pcm
+// RUN: %clang_cc1 -fmodules -fno-modules-error-recovery -std=c++14 -fmodule-file=%t/X.pcm -fmodule-file=%t/Y.pcm \
+// RUN:            -fmodules-local-submodule-visibility -verify %s -I%S/Inputs/merge-template-pattern-visibility
+
+#include "b.h"
+#include "d.h"
+
+// expected-no-diagnostics
+void g() {
+  CrossModuleMerge::B<int> bi;
+  CrossModuleMerge::C(0);
+}
diff --git a/test/Modules/merge-var-template-def.cpp b/test/Modules/merge-var-template-def.cpp
new file mode 100644
index 0000000..97a72a1
--- /dev/null
+++ b/test/Modules/merge-var-template-def.cpp
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -std=c++11 -verify %s
+// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -std=c++11 -verify -fmodules -Werror=undefined-internal -fmodules-local-submodule-visibility -fmodules-cache-path=%t -fimplicit-module-maps %s
+// expected-no-diagnostics
+
+#include "b2.h"
+const bool *y = &S<bool, false>::value;
diff --git a/test/Modules/pr28752.cpp b/test/Modules/pr28752.cpp
new file mode 100644
index 0000000..1c78961
--- /dev/null
+++ b/test/Modules/pr28752.cpp
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -I%S/Inputs/PR28752 -verify %s
+// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -fmodules -fmodule-map-file=%S/Inputs/PR28752/Subdir1/module.modulemap -fmodule-map-file=%S/Inputs/PR28752/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR28752 -I%S/Inputs/PR28752/Subdir1 -verify %s -fmodules-local-submodule-visibility
+
+#include "a.h"
+#include "Subdir1/c.h"
+#include <vector>
+
+class TClingClassInfo {
+  std::vector<int> fIterStack;
+};
+
+TClingClassInfo *a;
+class TClingBaseClassInfo {
+  TClingBaseClassInfo() { new TClingClassInfo(*a); }
+};
+
+namespace { struct Q; }
+bool *p = &A<Q>::b;
+
+// expected-no-diagnostics
+
diff --git a/test/SemaTemplate/instantiate-self.cpp b/test/SemaTemplate/instantiate-self.cpp
index cfe9025..916a01e 100644
--- a/test/SemaTemplate/instantiate-self.cpp
+++ b/test/SemaTemplate/instantiate-self.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++1z -verify -pedantic-errors %s
 
 // Check that we deal with cases where the instantiation of a class template
 // recursively requires the instantiation of the same template.
@@ -47,9 +47,8 @@
   A<int> a; // expected-note {{in instantiation of}}
 }
 
-// FIXME: PR12298: Recursive constexpr function template instantiation leads to
+// PR12298: Recursive constexpr function template instantiation leads to
 // stack overflow.
-#if 0
 namespace test5 {
   template<typename T> struct A {
     constexpr T f(T k) { return g(k); }
@@ -57,22 +56,20 @@
       return k ? f(k-1)+1 : 0;
     }
   };
-  // This should be accepted.
-  constexpr int x = A<int>().f(5);
+  constexpr int x = A<int>().f(5); // ok
 }
 
 namespace test6 {
   template<typename T> constexpr T f(T);
   template<typename T> constexpr T g(T t) {
-    typedef int arr[f(T())];
+    typedef int arr[f(T())]; // expected-error {{variable length array}}
     return t;
   }
   template<typename T> constexpr T f(T t) {
-    typedef int arr[g(T())];
+    typedef int arr[g(T())]; // expected-error {{zero size array}} expected-note {{instantiation of}}
     return t;
   }
-  // This should be ill-formed.
-  int n = f(0);
+  int n = f(0); // expected-note 2{{instantiation of}}
 }
 
 namespace test7 {
@@ -80,10 +77,94 @@
     return t;
   }
   template<typename T> constexpr T f(T t) {
-    typedef int arr[g(T())];
+    typedef int arr[g(T() + 1)];
     return t;
   }
-  // This should be accepted.
   int n = f(0);
 }
+
+namespace test8 {
+  template<typename T> struct A {
+    int n = A{}.n; // expected-error {{default member initializer for 'n' uses itself}} expected-note {{instantiation of default member init}}
+  };
+  A<int> ai = {}; // expected-note {{instantiation of default member init}}
+}
+
+namespace test9 {
+  template<typename T> struct A { enum class B; };
+  // FIXME: It'd be nice to give the "it has not yet been instantiated" diagnostic here.
+  template<typename T> enum class A<T>::B { k = A<T>::B::k2, k2 = k }; // expected-error {{no member named 'k2'}}
+  auto k = A<int>::B::k; // expected-note {{in instantiation of}}
+}
+
+namespace test10 {
+  template<typename T> struct A {
+    void f() noexcept(noexcept(f())); // expected-error {{exception specification of 'f' uses itself}} expected-note {{instantiation of}}
+  };
+  bool b = noexcept(A<int>().f()); // expected-note {{instantiation of}}
+}
+
+namespace test11 {
+  template<typename T> const int var = var<T>;
+  int k = var<int>;
+
+  template<typename T> struct X {
+    static const int k = X<T>::k;
+  };
+  template<typename T> const int X<T>::k;
+  int q = X<int>::k;
+
+  template<typename T> struct Y {
+    static const int k;
+  };
+  template<typename T> const int Y<T>::k = Y<T>::k;
+  int r = Y<int>::k;
+}
+
+namespace test12 {
+  template<typename T> int f(T t, int = f(T())) {} // expected-error {{recursive evaluation of default argument}} expected-note {{instantiation of}}
+  struct X {};
+  int q = f(X()); // expected-note {{instantiation of}}
+}
+
+namespace test13 {
+  struct A {
+    // Cycle via type of non-type template parameter.
+    template<typename T, typename T::template W<T>::type U = 0> struct W { using type = int; };
+    // Cycle via default template argument.
+    template<typename T, typename U = typename T::template X<T>> struct X {};
+    template<typename T, int U = T::template Y<T>::value> struct Y { static const int value = 0; };
+    template<typename T, template<typename> typename U = T::template Z<T>::template nested> struct Z { template<typename> struct nested; };
+  };
+  template<typename T> struct Wrap {
+    template<typename U> struct W : A::W<T> {};
+    template<typename U> struct X : A::X<T> {};
+    template<typename U> struct Y : A::Y<T> {};
+    template<typename U> struct Z : A::Z<T> {};
+  };
+  struct B {
+    template<typename U> struct W { using type = int; };
+    template<typename U> struct X {};
+    template<typename U> struct Y { static const int value = 0; };
+    template<typename U> struct Z { template<typename> struct nested; };
+  };
+
+  A::W<B> awb;
+  A::X<B> axb;
+  A::Y<B> ayb;
+  A::Z<B> azb;
+
+  A::W<Wrap<Wrap<B>>> awwwb;
+  A::X<Wrap<Wrap<B>>> axwwb;
+  A::Y<Wrap<Wrap<B>>> aywwb;
+  A::Z<Wrap<Wrap<B>>> azwwb;
+
+  // FIXME: These tests cause us to use too much stack and crash on a self-hosted debug build.
+  // FIXME: Check for recursion here and give a better diagnostic.
+#if 0
+  A::W<A> awa;
+  A::X<A> axa;
+  A::Y<A> aya;
+  A::Z<A> aza;
 #endif
+}
diff --git a/test/SemaTemplate/instantiation-depth-exception-spec.cpp b/test/SemaTemplate/instantiation-depth-exception-spec.cpp
index 6caa4a6..3f64811 100644
--- a/test/SemaTemplate/instantiation-depth-exception-spec.cpp
+++ b/test/SemaTemplate/instantiation-depth-exception-spec.cpp
@@ -1,11 +1,14 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s
 
-template<typename T> T go(T a) noexcept(noexcept(go(a))); // \
-// expected-error 16{{call to function 'go' that is neither visible}} \
-// expected-note 16{{'go' should be declared prior to the call site}} \
-// expected-error {{recursive template instantiation exceeded maximum depth of 16}}
+template<int N> struct X {
+  static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \
+// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
+// expected-note 9{{in instantiation of exception specification}} \
+// expected-note {{skipping 7 context}} \
+// expected-note {{use -ftemplate-depth}}
+};
 
 void f() {
-  int k = go(0); // \
-  // expected-note {{in instantiation of exception specification for 'go<int>' requested here}}
+  int k = X<0>::go(0); // \
+  // expected-note {{in instantiation of exception specification for 'go' requested here}}
 }
diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp
index c0b8bb2..17f84c1 100644
--- a/test/SemaTemplate/instantiation-depth.cpp
+++ b/test/SemaTemplate/instantiation-depth.cpp
@@ -19,13 +19,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s
 
 template<typename T> struct S {
-  S() noexcept(noexcept(T()));
-};
-struct T : S<T> {}; \
+  S() noexcept(noexcept(S<S>())); \
 // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
-// expected-note 4 {{in instantiation of exception spec}} \
+// expected-note 3 {{in instantiation of exception spec}} \
 // expected-note {{skipping 2 contexts in backtrace}} \
 // expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
-T t; // expected-note {{implicit default constructor for 'T' first required here}}
+};
+S<void> t; // expected-note {{in instantiation of exception spec}}
 
 #endif