Cache visibility of decls.

This unifies the linkage and visibility caching. I first implemented this when
working on pr13844, but the previous fixes removed the performance advantage of
this one.

This is still a step in the right direction for making linkage and visibility
cheap to use.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171048 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index a2c6da6..a3cdb40 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -104,8 +104,14 @@
   return LV;
 }
 
-/// getLVForDecl - Get the linkage and visibility for the given declaration.
-static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate);
+/// 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);
+}
 
 /// \brief Get the most restrictive linkage for the types and
 /// declarations in the given template argument list.
@@ -569,18 +575,18 @@
          i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
     Decl *child = *i;
     if (isa<NamedDecl>(child))
-      cast<NamedDecl>(child)->ClearLinkageCache();
+      cast<NamedDecl>(child)->ClearLVCache();
   }
 }
 
 void NamedDecl::anchor() { }
 
-void NamedDecl::ClearLinkageCache() {
+void NamedDecl::ClearLVCache() {
   // 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.
 
-  HasCachedLinkage = 0;
+  CacheValidAndVisibility = 0;
 
   // If we're changing the linkage of a class, we need to reset the
   // linkage of child declarations, too.
@@ -591,44 +597,44 @@
         dyn_cast<ClassTemplateDecl>(const_cast<NamedDecl*>(this))) {
     // Clear linkage for the template pattern.
     CXXRecordDecl *record = temp->getTemplatedDecl();
-    record->HasCachedLinkage = 0;
+    record->CacheValidAndVisibility = 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->ClearLinkageCache();
+      i->ClearLVCache();
   }
 
   // Clear cached linkage for function template decls, too.
   if (FunctionTemplateDecl *temp =
         dyn_cast<FunctionTemplateDecl>(const_cast<NamedDecl*>(this))) {
-    temp->getTemplatedDecl()->ClearLinkageCache();
+    temp->getTemplatedDecl()->ClearLVCache();
     for (FunctionTemplateDecl::spec_iterator
            i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
-      i->ClearLinkageCache();
+      i->ClearLVCache();
   }
     
 }
 
 Linkage NamedDecl::getLinkage() const {
-  if (HasCachedLinkage) {
-    assert(Linkage(CachedLinkage) ==
-             getLVForDecl(this, true).linkage());
-    return Linkage(CachedLinkage);
-  }
-
-  CachedLinkage = getLVForDecl(this, true).linkage();
-  HasCachedLinkage = 1;
-  return Linkage(CachedLinkage);
+  return getLinkageAndVisibility().linkage();
 }
 
 LinkageInfo NamedDecl::getLinkageAndVisibility() const {
-  LinkageInfo LI = getLVForDecl(this, false);
-  assert(!HasCachedLinkage || Linkage(CachedLinkage) == LI.linkage());
-  HasCachedLinkage = 1;
-  CachedLinkage = LI.linkage();
-  return LI;
+  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 LV = computeLVForDecl(this, false);
+  CachedLinkage = LV.linkage();
+  CacheValidAndVisibility = LV.visibility() + 1;
+  CachedVisibilityExplicit = LV.visibilityExplicit();
+  return LV;
 }
 
 llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
@@ -692,7 +698,7 @@
   return llvm::Optional<Visibility>();
 }
 
-static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
+static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
   // Objective-C: treat all Objective-C declarations as having external
   // linkage.
   switch (D->getKind()) {
@@ -1157,7 +1163,7 @@
 void VarDecl::setStorageClass(StorageClass SC) {
   assert(isLegalForVariable(SC));
   if (getStorageClass() != SC)
-    ClearLinkageCache();
+    ClearLVCache();
   
   VarDeclBits.SClass = SC;
 }
@@ -1653,6 +1659,7 @@
   Body = B;
   if (B)
     EndRangeLoc = B->getLocEnd();
+  ClearLVCache();
 }
 
 void FunctionDecl::setPure(bool P) {
@@ -1757,7 +1764,7 @@
 void FunctionDecl::setStorageClass(StorageClass SC) {
   assert(isLegalForFunction(SC));
   if (getStorageClass() != SC)
-    ClearLinkageCache();
+    ClearLVCache();
   
   SClass = SC;
 }
@@ -2527,8 +2534,8 @@
 void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { 
   TypedefNameDeclOrQualifier = TDD; 
   if (TypeForDecl)
-    const_cast<Type*>(TypeForDecl)->ClearLinkageCache();
-  ClearLinkageCache();
+    const_cast<Type*>(TypeForDecl)->ClearLVCache();
+  ClearLVCache();
 }
 
 void TagDecl::startDefinition() {