diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 0ca36cb..2ca8fe8 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -71,39 +71,6 @@ static LinkageInfo getLVForType(QualType T) {
   return LinkageInfo(P.first, P.second, T->isVisibilityExplicit());
 }
 
-/// \brief Get the most restrictive linkage for the types in the given
-/// template parameter list.
-static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *Params) {
-  LinkageInfo LV(ExternalLinkage, DefaultVisibility, false);
-  for (TemplateParameterList::const_iterator P = Params->begin(),
-                                          PEnd = Params->end();
-       P != PEnd; ++P) {
-    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
-      if (NTTP->isExpandedParameterPack()) {
-        for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {
-          QualType T = NTTP->getExpansionType(I);
-          if (!T->isDependentType())
-            LV.merge(getLVForType(T));
-        }
-        continue;
-      }
-
-      if (!NTTP->getType()->isDependentType()) {
-        LV.merge(getLVForType(NTTP->getType()));
-        continue;
-      }
-    }
-
-    if (TemplateTemplateParmDecl *TTP
-                                   = dyn_cast<TemplateTemplateParmDecl>(*P)) {
-      LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters()));
-    }
-  }
-
-  return LV;
-}
-
 /// getLVForDecl - Get the linkage and visibility for the given declaration.
 static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate);
 
@@ -376,15 +343,12 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
     // this is an explicit specialization with a visibility attribute.
     if (FunctionTemplateSpecializationInfo *specInfo
                                = Function->getTemplateSpecializationInfo()) {
-      LinkageInfo TempLV = getLVForDecl(specInfo->getTemplate(), true);
       const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(templateArgs,
                                                         OnlyTemplate);
       if (shouldConsiderTemplateVis(Function, specInfo)) {
-        LV.merge(TempLV);
         LV.mergeWithMin(ArgsLV);
       } else {
-        LV.mergeLinkage(TempLV);
         LV.mergeLinkage(ArgsLV);
       }
     }
@@ -404,18 +368,13 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
     // linkage of the template and template arguments.
     if (const ClassTemplateSpecializationDecl *spec
           = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
-      // From the template.
-      LinkageInfo TempLV = getLVForDecl(spec->getSpecializedTemplate(), true);
-
       // The arguments at which the template was instantiated.
       const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
                                                         OnlyTemplate);
       if (shouldConsiderTemplateVis(spec)) {
-        LV.merge(TempLV);
         LV.mergeWithMin(ArgsLV);
       } else {
-        LV.mergeLinkage(TempLV);
         LV.mergeLinkage(ArgsLV);
       }
     }
@@ -430,8 +389,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
 
   //     - a template, unless it is a function template that has
   //       internal linkage (Clause 14);
-  } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
-    LV.merge(getLVForTemplateParameterList(temp->getTemplateParameters()));
+  } else if (isa<TemplateDecl>(D)) {
+  // nothing to do.
   //     - a namespace (7.3), unless it is declared within an unnamed
   //       namespace.
   } else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) {
@@ -538,17 +497,10 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
       const TemplateArgumentList &TemplateArgs = *spec->TemplateArguments;
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
                                                         OnlyTemplate);
-      TemplateParameterList *TemplateParams =
-        spec->getTemplate()->getTemplateParameters();
-      LinkageInfo ParamsLV = getLVForTemplateParameterList(TemplateParams);
       if (shouldConsiderTemplateVis(MD, spec)) {
         LV.mergeWithMin(ArgsLV);
-        if (!OnlyTemplate)
-          LV.merge(ParamsLV);
       } else {
         LV.mergeLinkage(ArgsLV);
-        if (!OnlyTemplate)
-          LV.mergeLinkage(ParamsLV);
       }
     }
 
@@ -563,17 +515,10 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
       const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
                                                         OnlyTemplate);
-      TemplateParameterList *TemplateParams =
-        spec->getSpecializedTemplate()->getTemplateParameters();
-      LinkageInfo ParamsLV = getLVForTemplateParameterList(TemplateParams);
       if (shouldConsiderTemplateVis(spec)) {
         LV.mergeWithMin(ArgsLV);
-        if (!OnlyTemplate)
-          LV.merge(ParamsLV);
       } else {
         LV.mergeLinkage(ArgsLV);
-        if (!OnlyTemplate)
-          LV.mergeLinkage(ParamsLV);
       }
     }
 
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index d302214..2d2eef8 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -79,6 +79,22 @@ namespace test41 {
   // CHECK-HIDDEN: @_ZN6test413barE = external hidden global
 }
 
+namespace test48 {
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+
+  struct bar {
+    template<foo *z>
+    struct zed {
+    };
+  };
+
+  bar::zed<&x> y;
+  // CHECK: _ZN6test481yE = global
+  // CHECK-HIDDEN: _ZN6test481yE = hidden global
+}
+
 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
 // CHECK: @_ZN5Test71aE = hidden global
 // CHECK: @_ZN5Test71bE = global
@@ -881,3 +897,46 @@ namespace test47 {
   // CHECK: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
   // CHECK-HIDDEN: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
 }
+
+namespace test49 {
+  struct HIDDEN foo {
+  };
+
+  DEFAULT foo x;
+
+  struct bar {
+    template<foo *z>
+    void zed() {
+    }
+  };
+
+  template void bar::zed<&x>();
+  // CHECK: define weak_odr void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+}
+
+namespace test50 {
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+  template<foo *z>
+  struct DEFAULT bar {
+    void zed() {
+    }
+  };
+  template void bar<&x>::zed();
+  // CHECK: define weak_odr void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+  // CHECK-HIDDEN: define weak_odr void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+}
+
+namespace test51 {
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+  template<foo *z>
+  void DEFAULT zed() {
+  }
+  template void zed<&x>();
+  // CHECK: define weak_odr void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+  // CHECK-HIDDEN: define weak_odr void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+}
