diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 55464d4..71e4a9e 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -277,15 +277,9 @@ public:
       if (visibility() < V)
         return;
 
-      // FIXME: this
-      // If this visibility is explicit, keep it.
-      if (visibilityExplicit() && !E)
-        return;
-
-      // should be replaced with this
       // Don't lose the explicit bit for nothing
-      //      if (visibility() == V && visibilityExplicit())
-      //        return;
+      if (visibility() == V && visibilityExplicit())
+        return;
 
       setVisibility(V, E);
     }
@@ -304,11 +298,6 @@ public:
       mergeLinkage(Other);
       mergeVisibilityWithMin(Other);
     }
-
-    friend LinkageInfo merge(LinkageInfo L, LinkageInfo R) {
-      L.merge(R);
-      return L;
-    }
   };
 
   /// \brief Determine what kind of linkage this entity has.
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index e8e0f35..444f884 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -93,6 +93,9 @@ class Attr {
   list<string> Namespaces = [];
   // Set to true for attributes with arguments which require delayed parsing. 
   bit LateParsed = 0;  
+  // Set to false to prevent an attribute from being propagated from a template
+  // to the instantiation.
+  bit Clone = 1;
   // Set to true for attributes which must be instantiated within templates
   bit TemplateDependent = 0;
   // Set to true for attributes which have handler in Sema.
@@ -562,6 +565,7 @@ def Uuid : InheritableAttr {
 }
 
 def Visibility : InheritableAttr {
+  let Clone = 0;
   let Spellings = ["visibility"];
   let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 870e252..365e437 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -122,7 +122,7 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
       break;
 
     case TemplateArgument::Type:
-      LV.merge(getLVForType(Args[I].getAsType()));
+      LV.mergeWithMin(getLVForType(Args[I].getAsType()));
       break;
 
     case TemplateArgument::Declaration:
@@ -130,7 +130,7 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
       // arguments, valid only in C++0x.
       if (Decl *D = Args[I].getAsDecl()) {
         if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
-          LV = merge(LV, getLVForDecl(ND, OnlyTemplate));
+          LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate));
       }
       break;
 
@@ -138,7 +138,7 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
     case TemplateArgument::TemplateExpansion:
       if (TemplateDecl *Template
                 = Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl())
-        LV.merge(getLVForDecl(Template, OnlyTemplate));
+        LV.mergeWithMin(getLVForDecl(Template, OnlyTemplate));
       break;
 
     case TemplateArgument::Pack:
@@ -158,14 +158,12 @@ getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
   return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), OnlyTemplate);
 }
 
-static bool shouldConsiderTemplateLV(const FunctionDecl *fn,
-                               const FunctionTemplateSpecializationInfo *spec) {
-  return !(spec->isExplicitSpecialization() &&
-           fn->hasAttr<VisibilityAttr>());
+static bool shouldConsiderTemplateLV(const FunctionDecl *fn) {
+  return !fn->hasAttr<VisibilityAttr>();
 }
 
 static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) {
-  return !(d->isExplicitSpecialization() && d->hasAttr<VisibilityAttr>());
+  return !d->hasAttr<VisibilityAttr>();
 }
 
 static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
@@ -376,7 +374,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
     // this is an explicit specialization with a visibility attribute.
     if (FunctionTemplateSpecializationInfo *specInfo
                                = Function->getTemplateSpecializationInfo()) {
-      if (shouldConsiderTemplateLV(Function, specInfo)) {
+      if (shouldConsiderTemplateLV(Function)) {
         LV.merge(getLVForDecl(specInfo->getTemplate(),
                               true));
         const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
@@ -407,8 +405,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
 
         // The arguments at which the template was instantiated.
         const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
-        LV.merge(getLVForTemplateArgumentList(TemplateArgs,
-                                              OnlyTemplate));
+        LV.mergeWithMin(getLVForTemplateArgumentList(TemplateArgs,
+                                                     OnlyTemplate));
       }
     }
 
@@ -527,7 +525,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
     // the template parameters and arguments.
     if (FunctionTemplateSpecializationInfo *spec
            = MD->getTemplateSpecializationInfo()) {
-      if (shouldConsiderTemplateLV(MD, spec)) {
+      if (shouldConsiderTemplateLV(MD)) {
         LV.mergeWithMin(getLVForTemplateArgumentList(*spec->TemplateArguments,
                                                      OnlyTemplate));
         if (!OnlyTemplate)
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c7bd99c..75e70f2 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -102,7 +102,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
     } else {
       Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
                                                          *this, TemplateArgs);
-      New->addAttr(NewAttr);
+      if (NewAttr)
+        New->addAttr(NewAttr);
     }
   }
 }
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index b9ed373..c398d6f 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -536,9 +536,7 @@ namespace PR10113 {
   };
   template class foo::bar<zed>;
   // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
-
-  // FIXME: This should be hidden as zed is hidden.
-  // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
 }
 
 namespace PR11690 {
@@ -569,9 +567,7 @@ namespace PR11690_2 {
   };
   template class foo::zed<baz>;
   // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
-
-  // FIXME: This should be hidden as baz is hidden.
-  // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
 }
 
 namespace test23 {
@@ -682,3 +678,15 @@ namespace test34 {
   // CHECK: define weak_odr void @_ZN6test343barINS_3fooEEEvv
   // CHECK-HIDDEN: define weak_odr void @_ZN6test343barINS_3fooEEEvv
 }
+
+namespace test35 {
+  template<typename T1, typename T2>
+    class DEFAULT foo {
+    void bar() {}
+  };
+  class DEFAULT S1 {};
+  struct HIDDEN S2 {};
+  template class foo<S1, S2>;
+  // CHECK: define weak_odr hidden void @_ZN6test353fooINS_2S1ENS_2S2EE3barEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test353fooINS_2S1ENS_2S2EE3barEv
+}
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 7951fc4..3d44898 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -981,6 +981,14 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) {
     Record &R = **I;
 
     OS << "    case attr::" << R.getName() << ": {\n";
+    bool ShouldClone = R.getValueAsBit("Clone");
+
+    if (!ShouldClone) {
+      OS << "      return NULL;\n";
+      OS << "    }\n";
+      continue;
+    }
+
     OS << "      const " << R.getName() << "Attr *A = cast<"
        << R.getName() << "Attr>(At);\n";
     bool TDependent = R.getValueAsBit("TemplateDependent");
