diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 12b6c4a980703961ddfe0aaa45e6aab450012684..da12a5f5917dad54f5d26d197afdfd21b2062d4e 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -109,6 +109,7 @@ class NamedDecl : public Decl {
 
 private:
   NamedDecl *getUnderlyingDeclImpl();
+  void verifyLinkage() const;
 
 protected:
   NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -228,12 +229,6 @@ public:
              "Enum truncated!");
     }
 
-    bool operator==(const LinkageInfo &Other) {
-      return linkage_ == Other.linkage_ &&
-	visibility_ == Other.visibility_ &&
-	explicit_ == Other.explicit_;
-    }
-
     static LinkageInfo external() {
       return LinkageInfo();
     }
@@ -329,7 +324,7 @@ public:
 
   /// \brief Clear the linkage cache in response to a change
   /// to the declaration.
-  void ClearLVCache();
+  void ClearLinkageCache();
 
   /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
   /// the underlying named decl.
@@ -3337,7 +3332,7 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
   // First one will point to this one as latest.
   First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
   if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this)))
-    ND->ClearLVCache();
+    ND->ClearLinkageCache();
 }
 
 // Inline function definitions.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c91284d54a000a9689b1895027714b3d31bed25b..115edf6d92219571fdb8367717524accb80d7aa4 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -242,7 +242,7 @@ private:
   SourceLocation Loc;
 
   /// DeclKind - This indicates which class this is.
-  unsigned DeclKind : 6;
+  unsigned DeclKind : 8;
 
   /// InvalidDecl - This indicates a semantic error occurred.
   unsigned InvalidDecl :  1;
@@ -284,16 +284,15 @@ protected:
   /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
   unsigned IdentifierNamespace : 12;
 
-  /// These fields are only valid for NamedDecls subclasses.
+  /// \brief Whether the \c CachedLinkage field is active.
+  ///
+  /// This field is only valid for NamedDecls subclasses.
+  mutable unsigned HasCachedLinkage : 1;
+
+  /// \brief If \c HasCachedLinkage, the linkage of this declaration.
   ///
-  /// \brief Nonzero if the cache (i.e. the bitfields here starting
-  /// with 'Cache') is valid.  If so, then this is a
-  /// LangOptions::VisibilityMode+1.
-  mutable unsigned CacheValidAndVisibility : 2;
-  /// \brief the linkage of this declaration.
+  /// This field is only valid for NamedDecls subclasses.
   mutable unsigned CachedLinkage : 2;
-  /// \brief true if the visibility is explicit.
-  mutable unsigned CachedVisibilityExplicit : 1;
 
   friend class ASTDeclWriter;
   friend class ASTDeclReader;
@@ -310,7 +309,7 @@ protected:
       HasAttrs(false), Implicit(false), Used(false), Referenced(false),
       Access(AS_none), FromASTFile(0), Hidden(0),
       IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
-      CacheValidAndVisibility(0)
+      HasCachedLinkage(0)
   {
     if (StatisticsEnabled) add(DK);
   }
@@ -320,7 +319,7 @@ protected:
       HasAttrs(false), Implicit(false), Used(false), Referenced(false),
       Access(AS_none), FromASTFile(0), Hidden(0),
       IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
-      CacheValidAndVisibility(0)
+      HasCachedLinkage(0)
   {
     if (StatisticsEnabled) add(DK);
   }
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 98e2b6fb469c4c54eee2af855214289cf556ce73..2f1b48eb0f44b3cd299c60ceb0fc6343eeb7dfdc 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1781,7 +1781,7 @@ public:
   std::pair<Linkage,Visibility> getLinkageAndVisibility() const;
 
   /// \brief Note that the linkage is no longer known.
-  void ClearLVCache();
+  void ClearLinkageCache();
 
   const char *getTypeClassName() const;
 
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 409219a5715633a5f223e417b4ce5b3189db729f..83e6d6bd286d195bb1a7024fe519b5e5bb73eb2b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -958,7 +958,6 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
          "Already noted what static data member was instantiated from");
   InstantiatedFromStaticDataMember[Inst] 
     = new (*this) MemberSpecializationInfo(Tmpl, TSK, PointOfInstantiation);
-  Inst->ClearLVCache();
 }
 
 FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bf5bfaaef10b3df043523c7f86ed594b9762a930..986430595bd61e228b2f95d907658e5a2d7a9229 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -104,14 +104,8 @@ getLVForTemplateParameterList(const TemplateParameterList *Params) {
   return LV;
 }
 
-/// Compute the linkage and visibility for the given declaration.
-static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate);
-
-static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
-  if (!OnlyTemplate)
-    return D->getLinkageAndVisibility();
-  return computeLVForDecl(D, OnlyTemplate);
-}
+/// getLVForDecl - Get the linkage and visibility for the given declaration.
+static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate);
 
 /// \brief Get the most restrictive linkage for the types and
 /// declarations in the given template argument list.
@@ -575,18 +569,18 @@ static void clearLinkageForClass(const CXXRecordDecl *record) {
          i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
     Decl *child = *i;
     if (isa<NamedDecl>(child))
-      cast<NamedDecl>(child)->ClearLVCache();
+      cast<NamedDecl>(child)->ClearLinkageCache();
   }
 }
 
 void NamedDecl::anchor() { }
 
-void NamedDecl::ClearLVCache() {
+void NamedDecl::ClearLinkageCache() {
   // Note that we can't skip clearing the linkage of children just
   // because the parent doesn't have cached linkage:  we don't cache
   // when computing linkage for parent contexts.
 
-  CacheValidAndVisibility = 0;
+  HasCachedLinkage = 0;
 
   // If we're changing the linkage of a class, we need to reset the
   // linkage of child declarations, too.
@@ -597,51 +591,66 @@ void NamedDecl::ClearLVCache() {
         dyn_cast<ClassTemplateDecl>(const_cast<NamedDecl*>(this))) {
     // Clear linkage for the template pattern.
     CXXRecordDecl *record = temp->getTemplatedDecl();
-    record->CacheValidAndVisibility = 0;
+    record->HasCachedLinkage = 0;
     clearLinkageForClass(record);
 
     // We need to clear linkage for specializations, too.
     for (ClassTemplateDecl::spec_iterator
            i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
-      i->ClearLVCache();
+      i->ClearLinkageCache();
   }
 
   // Clear cached linkage for function template decls, too.
   if (FunctionTemplateDecl *temp =
         dyn_cast<FunctionTemplateDecl>(const_cast<NamedDecl*>(this))) {
-    temp->getTemplatedDecl()->ClearLVCache();
+    temp->getTemplatedDecl()->ClearLinkageCache();
     for (FunctionTemplateDecl::spec_iterator
            i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
-      i->ClearLVCache();
+      i->ClearLinkageCache();
   }
     
 }
 
 Linkage NamedDecl::getLinkage() const {
-  return getLinkageAndVisibility().linkage();
+  if (HasCachedLinkage) {
+    assert(Linkage(CachedLinkage) ==
+           getLVForDecl(this, true).linkage());
+    return Linkage(CachedLinkage);
+  }
+
+  CachedLinkage = getLVForDecl(this, true).linkage();
+  HasCachedLinkage = 1;
+
+#ifndef NDEBUG
+  verifyLinkage();
+#endif
+
+  return Linkage(CachedLinkage);
 }
 
 LinkageInfo NamedDecl::getLinkageAndVisibility() const {
-  if (CacheValidAndVisibility) {
-    Linkage L = static_cast<Linkage>(CachedLinkage);
-    Visibility V = static_cast<Visibility>(CacheValidAndVisibility - 1);
-    bool Explicit = CachedVisibilityExplicit;
-    LinkageInfo LV(L, V, Explicit);
-    assert(LV == computeLVForDecl(this, false));
-    return LV;
+  LinkageInfo LI = getLVForDecl(this, false);
+  if (HasCachedLinkage) {
+    assert(Linkage(CachedLinkage) == LI.linkage());
+    return LI;
   }
-  LinkageInfo LV = computeLVForDecl(this, false);
-  CachedLinkage = LV.linkage();
-  CacheValidAndVisibility = LV.visibility() + 1;
-  CachedVisibilityExplicit = LV.visibilityExplicit();
+  HasCachedLinkage = 1;
+  CachedLinkage = LI.linkage();
 
 #ifndef NDEBUG
+  verifyLinkage();
+#endif
+
+  return LI;
+}
+
+void NamedDecl::verifyLinkage() const {
   // In C (because of gnu inline) and in c++ with microsoft extensions an
   // static can follow an extern, so we can have two decls with different
   // linkages.
   const LangOptions &Opts = getASTContext().getLangOpts();
   if (!Opts.CPlusPlus || Opts.MicrosoftExt)
-    return LV;
+    return;
 
   // We have just computed the linkage for this decl. By induction we know
   // that all other computed linkages match, check that the one we just computed
@@ -651,15 +660,12 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const {
     NamedDecl *T = cast<NamedDecl>(*I);
     if (T == this)
       continue;
-    if (T->CacheValidAndVisibility != 0) {
+    if (T->HasCachedLinkage != 0) {
       D = T;
       break;
     }
   }
   assert(!D || D->CachedLinkage == CachedLinkage);
-#endif
-
-  return LV;
 }
 
 llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
@@ -723,7 +729,7 @@ llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
   return llvm::Optional<Visibility>();
 }
 
-static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
+static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
   // Objective-C: treat all Objective-C declarations as having external
   // linkage.
   switch (D->getKind()) {
@@ -1192,7 +1198,7 @@ VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
 void VarDecl::setStorageClass(StorageClass SC) {
   assert(isLegalForVariable(SC));
   if (getStorageClass() != SC)
-    ClearLVCache();
+    ClearLinkageCache();
   
   VarDeclBits.SClass = SC;
 }
@@ -1714,9 +1720,6 @@ void FunctionDecl::setBody(Stmt *B) {
   Body = B;
   if (B)
     EndRangeLoc = B->getLocEnd();
-  for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); R != REnd;
-       ++R)
-    R->ClearLVCache();
 }
 
 void FunctionDecl::setPure(bool P) {
@@ -1825,7 +1828,7 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() {
 void FunctionDecl::setStorageClass(StorageClass SC) {
   assert(isLegalForFunction(SC));
   if (getStorageClass() != SC)
-    ClearLVCache();
+    ClearLinkageCache();
   
   SClass = SC;
 }
@@ -2595,8 +2598,8 @@ TagDecl* TagDecl::getCanonicalDecl() {
 void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { 
   TypedefNameDeclOrQualifier = TDD; 
   if (TypeForDecl)
-    const_cast<Type*>(TypeForDecl)->ClearLVCache();
-  ClearLVCache();
+    const_cast<Type*>(TypeForDecl)->ClearLinkageCache();
+  ClearLinkageCache();
 }
 
 void TagDecl::startDefinition() {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index bb79b9b57bf890ffae630ab71af457cf6d48e8b8..45ec4edbc581ece2f0925bda0a819f6ea0844976 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2190,7 +2190,7 @@ std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const {
   return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility());
 }
 
-void Type::ClearLVCache() {
+void Type::ClearLinkageCache() {
   TypeBits.CacheValidAndVisibility = 0;
   if (QualType(this, 0) != CanonicalType)
     CanonicalType->TypeBits.CacheValidAndVisibility = 0;
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 3bfb8f22b461aefc4996fdfd272f03e585040724..b212b3fee006603a5de334725a97609ada7fa731 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -321,7 +321,6 @@ void Sema::AddPushedVisibilityAttribute(Decl *D) {
     = (VisibilityAttr::VisibilityType) rawType;
   SourceLocation loc = Stack->back().second;
 
-  ND->ClearLVCache();
   D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
 }
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c3a2ad11230fe7d325c7bda489d33809ea754964..b9d141bc351aca5c04613d865c638cfe166e1b36 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1824,18 +1824,14 @@ DeclHasAttr(const Decl *D, const Attr *A) {
 
 bool Sema::mergeDeclAttribute(NamedDecl *D, InheritableAttr *Attr) {
   InheritableAttr *NewAttr = NULL;
-  if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr)) {
+  if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr))
     NewAttr = mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
                                     AA->getIntroduced(), AA->getDeprecated(),
                                     AA->getObsoleted(), AA->getUnavailable(),
                                     AA->getMessage());
-    if (NewAttr)
-      D->ClearLVCache();
-  } else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr)) {
+  else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr))
     NewAttr = mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility());
-    if (NewAttr)
-      D->ClearLVCache();
-  } else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
+  else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
     NewAttr = mergeDLLImportAttr(D, ImportA->getRange());
   else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr))
     NewAttr = mergeDLLExportAttr(D, ExportA->getRange());
@@ -6695,7 +6691,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
     }
     VDecl->setTypeSourceInfo(DeducedType);
     VDecl->setType(DeducedType->getType());
-    VDecl->ClearLVCache();
+    VDecl->ClearLinkageCache();
     
     // In ARC, infer lifetime.
     if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 225ee24d0fce3e81fc503465bf7bd87b4e8ca523..9c17d6eabdaad09307197319650012ee170807b8 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2043,7 +2043,6 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
   VersionTuple MergedDeprecated = Deprecated;
   VersionTuple MergedObsoleted = Obsoleted;
   bool FoundAny = false;
-  bool DroppedAny = false;
 
   if (D->hasAttrs()) {
     AttrVec &Attrs = D->getAttrs();
@@ -2078,7 +2077,6 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
         Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
         Diag(Range.getBegin(), diag::note_previous_attribute);
         Attrs.erase(Attrs.begin() + i);
-        DroppedAny = true;
         --e;
         continue;
       }
@@ -2098,7 +2096,6 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
                                 MergedIntroduced2, MergedDeprecated2,
                                 MergedObsoleted2)) {
         Attrs.erase(Attrs.begin() + i);
-        DroppedAny = true;
         --e;
         continue;
       }
@@ -2110,9 +2107,6 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
     }
   }
 
-  if (DroppedAny)
-    D->ClearLVCache();
-
   if (FoundAny &&
       MergedIntroduced == Introduced &&
       MergedDeprecated == Deprecated &&
@@ -2159,10 +2153,8 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
                                                       Deprecated.Version,
                                                       Obsoleted.Version,
                                                       IsUnavailable, Str);
-  if (NewAttr) {
+  if (NewAttr)
     D->addAttr(NewAttr);
-    ND->ClearLVCache();
-  }
 }
 
 VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
@@ -2179,8 +2171,6 @@ VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
     Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
     Diag(Range.getBegin(), diag::note_previous_attribute);
     D->dropAttr<VisibilityAttr>();
-    NamedDecl *ND = cast<NamedDecl>(D);
-    ND->ClearLVCache();
   }
   return ::new (Context) VisibilityAttr(Range, Context, Vis);
 }
@@ -2224,11 +2214,8 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   }
 
   VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
-  if (NewAttr) {
+  if (NewAttr)
     D->addAttr(NewAttr);
-    NamedDecl *ND = cast<NamedDecl>(D);
-    ND->ClearLVCache();
-  }
 }
 
 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 0681adda839f64f3f0f44b9c0b7a94cedbad7571..e5bc743e4da9de0ad217f6a1395b4e75f3d8952c 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
 
 // The trickery with optimization in the run line is to get IR
 // generation to emit available_externally function bodies, but not
@@ -147,3 +147,18 @@ namespace test5 {
   template <int Idx_nocapture> void Op() {
   }
 }
+
+namespace test6 {
+  // just don't crash.
+  template <typename T>
+  void f(T x) {
+  }
+  struct C {
+    static void g() {
+      f([](){});
+    }
+  };
+  void g() {
+    C::g();
+  }
+}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 014503911a49853a6bc39a6fd4bb976a41c910f7..a196dda643dcc7ab99b107bde26fcf8702ce5bc8 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -1112,3 +1112,47 @@ namespace test60 {
     // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
   }
 }
+
+namespace test61 {
+  template <typename T1>
+  struct Class1
+  {
+    void f1() { f2(); }
+    inline void f2();
+  };
+  template<>
+  inline void Class1<int>::f2()
+  {
+  }
+  void g(Class1<int> *x) {
+    x->f1();
+  }
+}
+namespace test61 {
+  // Just test that we don't crash. Currently we apply this attribute. Current
+  // gcc issues a warning about it being unused since "the type is already
+  // defined". We should probably do the same.
+  template class __attribute__ ((visibility("hidden"))) Class1<int>;
+}
+
+namespace test62 {
+  template <typename T1>
+  struct Class1
+  {
+    void f1() { f2(); }
+    inline void f2() {}
+  };
+  template<>
+  inline void Class1<int>::f2()
+  {
+  }
+  void g(Class1<int> *x) {
+    x->f2();
+  }
+}
+namespace test62 {
+  template class __attribute__ ((visibility("hidden"))) Class1<int>;
+  // Just test that we don't crash. Currently we apply this attribute. Current
+  // gcc issues a warning about it being unused since "the type is already
+  // defined". We should probably do the same.
+}