<div dir="ltr">This seems to cause UBSAN issues:<div><br></div><div>runtime error: load of value 4294967295, which is not a valid value for type 'clang::LVComputationKind'<br></div><div><br></div><div>See ASAN+UBSAN bot on Green Dragon: <a href="http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/4065/console">http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/4065/console</a></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 8, 2017 at 9:02 PM, George Burgess IV via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: gbiv<br>
Date: Tue Aug  8 21:02:49 2017<br>
New Revision: 310436<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=310436&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=310436&view=rev</a><br>
Log:<br>
[AST] Move visibility computations into a class; NFC<br>
<br>
This is patch 1 in a 2 patch series that aims to fix PR29160. Its goal<br>
is to cache decl visibility/linkage for the duration of each<br>
visibility+linkage query.<br>
<br>
The simplest way I can see to do this is to put the visibility<br>
calculation code that needs to (transitively) access this cache into a<br>
class, which is what this patch does. Actual caching will come in patch<br>
2. (Another way would be to keep the cache in ASTContext + manually<br>
invalidate it or something, but that felt way too subtle to me.)<br>
<br>
Caching visibility results across multiple queries seems a bit tricky,<br>
since the user can add visibility attributes ~whenever they want, and<br>
these attributes can apparently have far-reaching effects (e.g. class<br>
visibility extends to its members, ...). Because a cache that's dropped<br>
at the end of each top-level query seems to work nearly as well and<br>
doesn't require any eviction logic, I opted for that design.<br>
<br>
Added:<br>
    cfe/trunk/lib/AST/Linkage.h<br>
Modified:<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/AST/Type.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=310436&r1=310435&r2=310436&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Decl.cpp?rev=310436&r1=310435&<wbr>r2=310436&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Tue Aug  8 21:02:49 2017<br>
@@ -12,6 +12,7 @@<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
 #include "clang/AST/Decl.h"<br>
+#include "Linkage.h"<br>
 #include "clang/AST/ASTContext.h"<br>
 #include "clang/AST/ASTLambda.h"<br>
 #include "clang/AST/<wbr>ASTMutationListener.h"<br>
@@ -99,38 +100,6 @@ TranslationUnitDecl::<wbr>TranslationUnitDecl<br>
 // and 'matcher' is a type only matters when looking for attributes<br>
 // and settings from the immediate context.<br>
<br>
-const static unsigned IgnoreExplicitVisibilityBit = 2;<br>
-const static unsigned IgnoreAllVisibilityBit = 4;<br>
-<br>
-/// Kinds of LV computation.  The linkage side of the computation is<br>
-/// always the same, but different things can change how visibility is<br>
-/// computed.<br>
-enum LVComputationKind {<br>
-  /// Do an LV computation for, ultimately, a type.<br>
-  /// Visibility may be restricted by type visibility settings and<br>
-  /// the visibility of template arguments.<br>
-  LVForType = NamedDecl::VisibilityForType,<br>
-<br>
-  /// Do an LV computation for, ultimately, a non-type declaration.<br>
-  /// Visibility may be restricted by value visibility settings and<br>
-  /// the visibility of template arguments.<br>
-  LVForValue = NamedDecl::VisibilityForValue,<br>
-<br>
-  /// Do an LV computation for, ultimately, a type that already has<br>
-  /// some sort of explicit visibility.  Visibility may only be<br>
-  /// restricted by the visibility of template arguments.<br>
-  LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),<br>
-<br>
-  /// Do an LV computation for, ultimately, a non-type declaration<br>
-  /// that already has some sort of explicit visibility.  Visibility<br>
-  /// may only be restricted by the visibility of template arguments.<br>
-  LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),<br>
-<br>
-  /// Do an LV computation when we only care about the linkage.<br>
-  LVForLinkageOnly =<br>
-      LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit<br>
-};<br>
-<br>
 /// Does this computation kind permit us to consider additional<br>
 /// visibility settings from attributes and the like?<br>
 static bool hasExplicitVisibilityAlready(<wbr>LVComputationKind computation) {<br>
@@ -219,8 +188,8 @@ static Optional<Visibility> getVisibilit<br>
   return None;<br>
 }<br>
<br>
-static LinkageInfo<br>
-getLVForType(const Type &T, LVComputationKind computation) {<br>
+LinkageInfo LinkageComputer::getLVForType(<wbr>const Type &T,<br>
+                                          LVComputationKind computation) {<br>
   if (computation == LVForLinkageOnly)<br>
     return LinkageInfo(T.getLinkage(), DefaultVisibility, true);<br>
   return T.getLinkageAndVisibility();<br>
@@ -229,9 +198,8 @@ getLVForType(const Type &T, LVComputatio<br>
 /// \brief Get the most restrictive linkage for the types in the given<br>
 /// template parameter list.  For visibility purposes, template<br>
 /// parameters are part of the signature of a template.<br>
-static LinkageInfo<br>
-<wbr>getLVForTemplateParameterList(<wbr>const TemplateParameterList *Params,<br>
-                              LVComputationKind computation) {<br>
+LinkageInfo LinkageComputer::<wbr>getLVForTemplateParameterList(<br>
+    const TemplateParameterList *Params, LVComputationKind computation) {<br>
   LinkageInfo LV;<br>
   for (const NamedDecl *P : *Params) {<br>
     // Template type parameters are the most common and never<br>
@@ -283,10 +251,6 @@ getLVForTemplateParameterList(<wbr>const Temp<br>
   return LV;<br>
 }<br>
<br>
-/// getLVForDecl - Get the linkage and visibility for the given declaration.<br>
-static LinkageInfo getLVForDecl(const NamedDecl *D,<br>
-                                LVComputationKind computation);<br>
-<br>
 static const Decl *<wbr>getOutermostFuncOrBlockContext<wbr>(const Decl *D) {<br>
   const Decl *Ret = nullptr;<br>
   const DeclContext *DC = D->getDeclContext();<br>
@@ -303,8 +267,9 @@ static const Decl *getOutermostFuncOrBlo<br>
 ///<br>
 /// Note that we don't take an LVComputationKind because we always<br>
 /// want to honor the visibility of template arguments in the same way.<br>
-static LinkageInfo getLVForTemplateArgumentList(<wbr>ArrayRef<TemplateArgument> Args,<br>
-                                                LVComputationKind computation) {<br>
+LinkageInfo<br>
+LinkageComputer::<wbr>getLVForTemplateArgumentList(<wbr>ArrayRef<TemplateArgument> Args,<br>
+                                              LVComputationKind computation) {<br>
   LinkageInfo LV;<br>
<br>
   for (const TemplateArgument &Arg : Args) {<br>
@@ -346,9 +311,9 @@ static LinkageInfo getLVForTemplateArgum<br>
   return LV;<br>
 }<br>
<br>
-static LinkageInfo<br>
-getLVForTemplateArgumentList(<wbr>const TemplateArgumentList &TArgs,<br>
-                             LVComputationKind computation) {<br>
+LinkageInfo<br>
+LinkageComputer::<wbr>getLVForTemplateArgumentList(<wbr>const TemplateArgumentList &TArgs,<br>
+                                              LVComputationKind computation) {<br>
   return getLVForTemplateArgumentList(<wbr>TArgs.asArray(), computation);<br>
 }<br>
<br>
@@ -371,10 +336,10 @@ static bool shouldConsiderTemplateVisibi<br>
 /// LVForValue.<br>
 ///<br>
 /// \param[out] LV the computation to use for the parent<br>
-static void<br>
-mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,<br>
-                const FunctionTemplateSpecialization<wbr>Info *specInfo,<br>
-                LVComputationKind computation) {<br>
+void LinkageComputer::<wbr>mergeTemplateLV(<br>
+    LinkageInfo &LV, const FunctionDecl *fn,<br>
+    const FunctionTemplateSpecialization<wbr>Info *specInfo,<br>
+    LVComputationKind computation) {<br>
   bool considerVisibility =<br>
     shouldConsiderTemplateVisibili<wbr>ty(fn, specInfo);<br>
<br>
@@ -449,9 +414,9 @@ static bool shouldConsiderTemplateVisibi<br>
<br>
 /// Merge in template-related linkage and visibility for the given<br>
 /// class template specialization.<br>
-static void mergeTemplateLV(LinkageInfo &LV,<br>
-                            const ClassTemplateSpecializationDec<wbr>l *spec,<br>
-                            LVComputationKind computation) {<br>
+void LinkageComputer::<wbr>mergeTemplateLV(<br>
+    LinkageInfo &LV, const ClassTemplateSpecializationDec<wbr>l *spec,<br>
+    LVComputationKind computation) {<br>
   bool considerVisibility = shouldConsiderTemplateVisibili<wbr>ty(spec, computation);<br>
<br>
   // Merge information from the template parameters, but ignore<br>
@@ -501,9 +466,9 @@ static bool shouldConsiderTemplateVisibi<br>
 /// Merge in template-related linkage and visibility for the given<br>
 /// variable template specialization. As usual, follow class template<br>
 /// specialization logic up to initialization.<br>
-static void mergeTemplateLV(LinkageInfo &LV,<br>
-                            const VarTemplateSpecializationDecl *spec,<br>
-                            LVComputationKind computation) {<br>
+void LinkageComputer::<wbr>mergeTemplateLV(LinkageInfo &LV,<br>
+                                      const VarTemplateSpecializationDecl *spec,<br>
+                                      LVComputationKind computation) {<br>
   bool considerVisibility = shouldConsiderTemplateVisibili<wbr>ty(spec, computation);<br>
<br>
   // Merge information from the template parameters, but ignore<br>
@@ -603,8 +568,9 @@ static LinkageInfo getExternalLinkageFor<br>
   return LinkageInfo::external();<br>
 }<br>
<br>
-static LinkageInfo getLVForNamespaceScopeDecl(<wbr>const NamedDecl *D,<br>
-                                              LVComputationKind computation) {<br>
+LinkageInfo<br>
+LinkageComputer::<wbr>getLVForNamespaceScopeDecl(<wbr>const NamedDecl *D,<br>
+                                            LVComputationKind computation) {<br>
   assert(D->getDeclContext()-><wbr>getRedeclContext()-><wbr>isFileContext() &&<br>
          "Not a name having namespace scope");<br>
   ASTContext &Context = D->getASTContext();<br>
@@ -883,8 +849,9 @@ static LinkageInfo getLVForNamespaceScop<br>
   return LV;<br>
 }<br>
<br>
-static LinkageInfo getLVForClassMember(const NamedDecl *D,<br>
-                                       LVComputationKind computation) {<br>
+LinkageInfo<br>
+LinkageComputer::<wbr>getLVForClassMember(const NamedDecl *D,<br>
+                                     LVComputationKind computation) {<br>
   // Only certain class members have linkage.  Note that fields don't<br>
   // really have linkage, but it's convenient to say they do for the<br>
   // purposes of calculating linkage of pointer-to-data-member<br>
@@ -1041,15 +1008,13 @@ static LinkageInfo getLVForClassMember(c<br>
<br>
 void NamedDecl::anchor() { }<br>
<br>
-static LinkageInfo computeLVForDecl(const NamedDecl *D,<br>
-                                    LVComputationKind computation);<br>
-<br>
 bool NamedDecl::isLinkageValid() const {<br>
   if (!hasCachedLinkage())<br>
     return true;<br>
<br>
-  return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==<br>
-         getCachedLinkage();<br>
+  Linkage L =<br>
+      LinkageComputer{}.<wbr>computeLVForDecl(this, LVForLinkageOnly).getLinkage()<wbr>;<br>
+  return L == getCachedLinkage();<br>
 }<br>
<br>
 ObjCStringFormatFamily NamedDecl::<wbr>getObjCFStringFormattingFamily<wbr>() const {<br>
@@ -1068,13 +1033,11 @@ ObjCStringFormatFamily NamedDecl::getObj<br>
 Linkage NamedDecl::getLinkageInternal(<wbr>) const {<br>
   // We don't care about visibility here, so ask for the cheapest<br>
   // possible visibility analysis.<br>
-  return getLVForDecl(this, LVForLinkageOnly).getLinkage()<wbr>;<br>
+  return LinkageComputer{}.<wbr>getLVForDecl(this, LVForLinkageOnly).getLinkage()<wbr>;<br>
 }<br>
<br>
 LinkageInfo NamedDecl::<wbr>getLinkageAndVisibility() const {<br>
-  LVComputationKind computation =<br>
-    (usesTypeVisibility(this) ? LVForType : LVForValue);<br>
-  return getLVForDecl(this, computation);<br>
+  return LinkageComputer{}.<wbr>getDeclLinkageAndVisibility(<wbr>this);<br>
 }<br>
<br>
 static Optional<Visibility><br>
@@ -1152,8 +1115,9 @@ NamedDecl::<wbr>getExplicitVisibility(Explici<br>
   return getExplicitVisibilityAux(this, kind, false);<br>
 }<br>
<br>
-static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,<br>
-                                   LVComputationKind computation) {<br>
+LinkageInfo LinkageComputer::<wbr>getLVForClosure(const DeclContext *DC,<br>
+                                             Decl *ContextDecl,<br>
+                                             LVComputationKind computation) {<br>
   // This lambda has its linkage/visibility determined by its owner.<br>
   if (ContextDecl) {<br>
     if (isa<ParmVarDecl>(ContextDecl)<wbr>)<br>
@@ -1170,8 +1134,8 @@ static LinkageInfo getLVForClosure(const<br>
   return LinkageInfo::external();<br>
 }<br>
<br>
-static LinkageInfo getLVForLocalDecl(const NamedDecl *D,<br>
-                                     LVComputationKind computation) {<br>
+LinkageInfo LinkageComputer::<wbr>getLVForLocalDecl(const NamedDecl *D,<br>
+                                               LVComputationKind computation) {<br>
   if (const auto *Function = dyn_cast<FunctionDecl>(D)) {<br>
     if (Function-><wbr>isInAnonymousNamespace() &&<br>
         !Function->isInExternCContext(<wbr>))<br>
@@ -1264,8 +1228,8 @@ getOutermostEnclosingLambda(<wbr>const CXXRec<br>
   return Ret;<br>
 }<br>
<br>
-static LinkageInfo computeLVForDecl(const NamedDecl *D,<br>
-                                    LVComputationKind computation) {<br>
+LinkageInfo LinkageComputer::<wbr>computeLVForDecl(const NamedDecl *D,<br>
+                                              LVComputationKind computation) {<br>
   // Internal_linkage attribute overrides other considerations.<br>
   if (D->hasAttr<<wbr>InternalLinkageAttr>())<br>
     return getInternalLinkageFor(D);<br>
@@ -1384,56 +1348,51 @@ static LinkageInfo computeLVForDecl(cons<br>
   return LinkageInfo::none();<br>
 }<br>
<br>
-namespace clang {<br>
-class LinkageComputer {<br>
-public:<br>
-  static LinkageInfo getLVForDecl(const NamedDecl *D,<br>
-                                  LVComputationKind computation) {<br>
-    // Internal_linkage attribute overrides other considerations.<br>
-    if (D->hasAttr<<wbr>InternalLinkageAttr>())<br>
-      return getInternalLinkageFor(D);<br>
-<br>
-    if (computation == LVForLinkageOnly && D->hasCachedLinkage())<br>
-      return LinkageInfo(D-><wbr>getCachedLinkage(), DefaultVisibility, false);<br>
-<br>
-    LinkageInfo LV = computeLVForDecl(D, computation);<br>
-    if (D->hasCachedLinkage())<br>
-      assert(D->getCachedLinkage() == LV.getLinkage());<br>
+/// getLVForDecl - Get the linkage and visibility for the given declaration.<br>
+LinkageInfo LinkageComputer::getLVForDecl(<wbr>const NamedDecl *D,<br>
+                                          LVComputationKind computation) {<br>
+  // Internal_linkage attribute overrides other considerations.<br>
+  if (D->hasAttr<<wbr>InternalLinkageAttr>())<br>
+    return getInternalLinkageFor(D);<br>
+<br>
+  if (computation == LVForLinkageOnly && D->hasCachedLinkage())<br>
+    return LinkageInfo(D-><wbr>getCachedLinkage(), DefaultVisibility, false);<br>
<br>
-    D->setCachedLinkage(LV.<wbr>getLinkage());<br>
+  LinkageInfo LV = computeLVForDecl(D, computation);<br>
+  if (D->hasCachedLinkage())<br>
+    assert(D->getCachedLinkage() == LV.getLinkage());<br>
+<br>
+  D->setCachedLinkage(LV.<wbr>getLinkage());<br>
<br>
 #ifndef NDEBUG<br>
-    // In C (because of gnu inline) and in c++ with microsoft extensions an<br>
-    // static can follow an extern, so we can have two decls with different<br>
-    // linkages.<br>
-    const LangOptions &Opts = D->getASTContext().<wbr>getLangOpts();<br>
-    if (!Opts.CPlusPlus || Opts.MicrosoftExt)<br>
-      return LV;<br>
+  // In C (because of gnu inline) and in c++ with microsoft extensions an<br>
+  // static can follow an extern, so we can have two decls with different<br>
+  // linkages.<br>
+  const LangOptions &Opts = D->getASTContext().<wbr>getLangOpts();<br>
+  if (!Opts.CPlusPlus || Opts.MicrosoftExt)<br>
+    return LV;<br>
<br>
-    // We have just computed the linkage for this decl. By induction we know<br>
-    // that all other computed linkages match, check that the one we just<br>
-    // computed also does.<br>
-    NamedDecl *Old = nullptr;<br>
-    for (auto I : D->redecls()) {<br>
-      auto *T = cast<NamedDecl>(I);<br>
-      if (T == D)<br>
-        continue;<br>
-      if (!T->isInvalidDecl() && T->hasCachedLinkage()) {<br>
-        Old = T;<br>
-        break;<br>
-      }<br>
+  // We have just computed the linkage for this decl. By induction we know<br>
+  // that all other computed linkages match, check that the one we just<br>
+  // computed also does.<br>
+  NamedDecl *Old = nullptr;<br>
+  for (auto I : D->redecls()) {<br>
+    auto *T = cast<NamedDecl>(I);<br>
+    if (T == D)<br>
+      continue;<br>
+    if (!T->isInvalidDecl() && T->hasCachedLinkage()) {<br>
+      Old = T;<br>
+      break;<br>
     }<br>
-    assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());<br>
+  }<br>
+  assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());<br>
 #endif<br>
<br>
-    return LV;<br>
-  }<br>
-};<br>
+  return LV;<br>
 }<br>
<br>
-static LinkageInfo getLVForDecl(const NamedDecl *D,<br>
-                                LVComputationKind computation) {<br>
-  return clang::LinkageComputer::<wbr>getLVForDecl(D, computation);<br>
+LinkageInfo LinkageComputer::<wbr>getDeclLinkageAndVisibility(<wbr>const NamedDecl *D) {<br>
+  return getLVForDecl(D, usesTypeVisibility(D) ? LVForType : LVForValue);<br>
 }<br>
<br>
 void NamedDecl::printName(raw_<wbr>ostream &os) const {<br>
<br>
Added: cfe/trunk/lib/AST/Linkage.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Linkage.h?rev=310436&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Linkage.h?rev=310436&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Linkage.h (added)<br>
+++ cfe/trunk/lib/AST/Linkage.h Tue Aug  8 21:02:49 2017<br>
@@ -0,0 +1,114 @@<br>
+//===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+//<br>
+// This file provides AST-internal utilities for linkage and visibility<br>
+// calculation.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_LIB_AST_LINKAGE_H<br>
+#define LLVM_CLANG_LIB_AST_LINKAGE_H<br>
+<br>
+#include "clang/AST/Decl.h"<br>
+#include "clang/AST/DeclCXX.h"<br>
+#include "clang/AST/Type.h"<br>
+#include "llvm/ADT/DenseMap.h"<br>
+<br>
+namespace clang {<br>
+enum : unsigned {<br>
+  IgnoreExplicitVisibilityBit = 2,<br>
+  IgnoreAllVisibilityBit = 4<br>
+};<br>
+<br>
+/// Kinds of LV computation.  The linkage side of the computation is<br>
+/// always the same, but different things can change how visibility is<br>
+/// computed.<br>
+enum LVComputationKind {<br>
+  /// Do an LV computation for, ultimately, a type.<br>
+  /// Visibility may be restricted by type visibility settings and<br>
+  /// the visibility of template arguments.<br>
+  LVForType = NamedDecl::VisibilityForType,<br>
+<br>
+  /// Do an LV computation for, ultimately, a non-type declaration.<br>
+  /// Visibility may be restricted by value visibility settings and<br>
+  /// the visibility of template arguments.<br>
+  LVForValue = NamedDecl::VisibilityForValue,<br>
+<br>
+  /// Do an LV computation for, ultimately, a type that already has<br>
+  /// some sort of explicit visibility.  Visibility may only be<br>
+  /// restricted by the visibility of template arguments.<br>
+  LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),<br>
+<br>
+  /// Do an LV computation for, ultimately, a non-type declaration<br>
+  /// that already has some sort of explicit visibility.  Visibility<br>
+  /// may only be restricted by the visibility of template arguments.<br>
+  LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),<br>
+<br>
+  /// Do an LV computation when we only care about the linkage.<br>
+  LVForLinkageOnly =<br>
+      LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit<br>
+};<br>
+<br>
+class LinkageComputer {<br>
+  LinkageInfo getLVForTemplateArgumentList(<wbr>ArrayRef<TemplateArgument> Args,<br>
+                                           LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForTemplateArgumentList(<wbr>const TemplateArgumentList &TArgs,<br>
+                                           LVComputationKind computation);<br>
+<br>
+  void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,<br>
+                       const FunctionTemplateSpecialization<wbr>Info *specInfo,<br>
+                       LVComputationKind computation);<br>
+<br>
+  void mergeTemplateLV(LinkageInfo &LV,<br>
+                       const ClassTemplateSpecializationDec<wbr>l *spec,<br>
+                       LVComputationKind computation);<br>
+<br>
+  void mergeTemplateLV(LinkageInfo &LV,<br>
+                       const VarTemplateSpecializationDecl *spec,<br>
+                       LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForNamespaceScopeDecl(<wbr>const NamedDecl *D,<br>
+                                         LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForClassMember(const NamedDecl *D,<br>
+                                  LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,<br>
+                              LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForLocalDecl(const NamedDecl *D,<br>
+                                LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForType(const Type &T, LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForTemplateParameterList(<wbr>const TemplateParameterList *Params,<br>
+                                            LVComputationKind computation);<br>
+<br>
+public:<br>
+  LinkageInfo computeLVForDecl(const NamedDecl *D,<br>
+                               LVComputationKind computation);<br>
+<br>
+  LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);<br>
+<br>
+  LinkageInfo computeTypeLinkageInfo(const Type *T);<br>
+  LinkageInfo computeTypeLinkageInfo(<wbr>QualType T) {<br>
+    return computeTypeLinkageInfo(T.<wbr>getTypePtr());<br>
+  }<br>
+<br>
+  LinkageInfo getDeclLinkageAndVisibility(<wbr>const NamedDecl *D);<br>
+<br>
+  LinkageInfo getTypeLinkageAndVisibility(<wbr>const Type *T);<br>
+  LinkageInfo getTypeLinkageAndVisibility(<wbr>QualType T) {<br>
+    return getTypeLinkageAndVisibility(T.<wbr>getTypePtr());<br>
+  }<br>
+};<br>
+} // namespace clang<br>
+<br>
+#endif<br>
<br>
Modified: cfe/trunk/lib/AST/Type.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=310436&r1=310435&r2=310436&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Type.cpp?rev=310436&r1=310435&<wbr>r2=310436&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Type.cpp (original)<br>
+++ cfe/trunk/lib/AST/Type.cpp Tue Aug  8 21:02:49 2017<br>
@@ -12,6 +12,7 @@<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
 #include "clang/AST/Type.h"<br>
+#include "Linkage.h"<br>
 #include "clang/AST/ASTContext.h"<br>
 #include "clang/AST/Attr.h"<br>
 #include "clang/AST/CharUnits.h"<br>
@@ -3428,9 +3429,7 @@ bool Type::hasUnnamedOrLocalType() const<br>
   return TypeBits.<wbr>hasLocalOrUnnamedType();<br>
 }<br>
<br>
-static LinkageInfo computeLinkageInfo(QualType T);<br>
-<br>
-static LinkageInfo computeLinkageInfo(const Type *T) {<br>
+LinkageInfo LinkageComputer::<wbr>computeTypeLinkageInfo(const Type *T) {<br>
   switch (T->getTypeClass()) {<br>
 #define TYPE(Class,Base)<br>
 #define NON_CANONICAL_TYPE(Class,Base) case Type::Class:<br>
@@ -3457,72 +3456,75 @@ static LinkageInfo computeLinkageInfo(co<br>
     return cast<TagType>(T)->getDecl()-><wbr>getLinkageAndVisibility();<br>
<br>
   case Type::Complex:<br>
-    return computeLinkageInfo(cast<<wbr>ComplexType>(T)-><wbr>getElementType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>ComplexType>(T)-><wbr>getElementType());<br>
   case Type::Pointer:<br>
-    return computeLinkageInfo(cast<<wbr>PointerType>(T)-><wbr>getPointeeType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>PointerType>(T)-><wbr>getPointeeType());<br>
   case Type::BlockPointer:<br>
-    return computeLinkageInfo(cast<<wbr>BlockPointerType>(T)-><wbr>getPointeeType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>BlockPointerType>(T)-><wbr>getPointeeType());<br>
   case Type::LValueReference:<br>
   case Type::RValueReference:<br>
-    return computeLinkageInfo(cast<<wbr>ReferenceType>(T)-><wbr>getPointeeType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>ReferenceType>(T)-><wbr>getPointeeType());<br>
   case Type::MemberPointer: {<br>
     const MemberPointerType *MPT = cast<MemberPointerType>(T);<br>
-    LinkageInfo LV = computeLinkageInfo(MPT-><wbr>getClass());<br>
-    LV.merge(computeLinkageInfo(<wbr>MPT->getPointeeType()));<br>
+    LinkageInfo LV = computeTypeLinkageInfo(MPT-><wbr>getClass());<br>
+    LV.merge(<wbr>computeTypeLinkageInfo(MPT-><wbr>getPointeeType()));<br>
     return LV;<br>
   }<br>
   case Type::ConstantArray:<br>
   case Type::IncompleteArray:<br>
   case Type::VariableArray:<br>
-    return computeLinkageInfo(cast<<wbr>ArrayType>(T)->getElementType(<wbr>));<br>
+    return computeTypeLinkageInfo(cast<<wbr>ArrayType>(T)->getElementType(<wbr>));<br>
   case Type::Vector:<br>
   case Type::ExtVector:<br>
-    return computeLinkageInfo(cast<<wbr>VectorType>(T)-><wbr>getElementType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>VectorType>(T)-><wbr>getElementType());<br>
   case Type::FunctionNoProto:<br>
-    return computeLinkageInfo(cast<<wbr>FunctionType>(T)-><wbr>getReturnType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>FunctionType>(T)-><wbr>getReturnType());<br>
   case Type::FunctionProto: {<br>
     const FunctionProtoType *FPT = cast<FunctionProtoType>(T);<br>
-    LinkageInfo LV = computeLinkageInfo(FPT-><wbr>getReturnType());<br>
+    LinkageInfo LV = computeTypeLinkageInfo(FPT-><wbr>getReturnType());<br>
     for (const auto &ai : FPT->param_types())<br>
-      LV.merge(computeLinkageInfo(<wbr>ai));<br>
+      LV.merge(<wbr>computeTypeLinkageInfo(ai));<br>
     return LV;<br>
   }<br>
   case Type::ObjCInterface:<br>
     return cast<ObjCInterfaceType>(T)-><wbr>getDecl()-><wbr>getLinkageAndVisibility();<br>
   case Type::ObjCObject:<br>
-    return computeLinkageInfo(cast<<wbr>ObjCObjectType>(T)-><wbr>getBaseType());<br>
+    return computeTypeLinkageInfo(cast<<wbr>ObjCObjectType>(T)-><wbr>getBaseType());<br>
   case Type::ObjCObjectPointer:<br>
-    return computeLinkageInfo(cast<<wbr>ObjCObjectPointerType>(T)-><wbr>getPointeeType());<br>
+    return computeTypeLinkageInfo(<br>
+        cast<ObjCObjectPointerType>(T)<wbr>->getPointeeType());<br>
   case Type::Atomic:<br>
-    return computeLinkageInfo(cast<<wbr>AtomicType>(T)->getValueType()<wbr>);<br>
+    return computeTypeLinkageInfo(cast<<wbr>AtomicType>(T)->getValueType()<wbr>);<br>
   case Type::Pipe:<br>
-    return computeLinkageInfo(cast<<wbr>PipeType>(T)->getElementType()<wbr>);<br>
+    return computeTypeLinkageInfo(cast<<wbr>PipeType>(T)->getElementType()<wbr>);<br>
   }<br>
<br>
   llvm_unreachable("unhandled type class");<br>
 }<br>
<br>
-static LinkageInfo computeLinkageInfo(QualType T) {<br>
-  return computeLinkageInfo(T.<wbr>getTypePtr());<br>
-}<br>
-<br>
 bool Type::isLinkageValid() const {<br>
   if (!TypeBits.isCacheValid())<br>
     return true;<br>
<br>
-  return computeLinkageInfo(<wbr>getCanonicalTypeInternal()).<wbr>getLinkage() ==<br>
-    TypeBits.getLinkage();<br>
+  Linkage L = LinkageComputer{}<br>
+                  .computeTypeLinkageInfo(<wbr>getCanonicalTypeInternal())<br>
+                  .getLinkage();<br>
+  return L == TypeBits.getLinkage();<br>
 }<br>
<br>
-LinkageInfo Type::getLinkageAndVisibility(<wbr>) const {<br>
-  if (!isCanonicalUnqualified())<br>
-    return computeLinkageInfo(<wbr>getCanonicalTypeInternal());<br>
+LinkageInfo LinkageComputer::<wbr>getTypeLinkageAndVisibility(<wbr>const Type *T) {<br>
+  if (!T->isCanonicalUnqualified())<br>
+    return computeTypeLinkageInfo(T-><wbr>getCanonicalTypeInternal());<br>
<br>
-  LinkageInfo LV = computeLinkageInfo(this);<br>
-  assert(LV.getLinkage() == getLinkage());<br>
+  LinkageInfo LV = computeTypeLinkageInfo(T);<br>
+  assert(LV.getLinkage() == T->getLinkage());<br>
   return LV;<br>
 }<br>
<br>
+LinkageInfo Type::getLinkageAndVisibility(<wbr>) const {<br>
+  return LinkageComputer{}.<wbr>getTypeLinkageAndVisibility(<wbr>this);<br>
+}<br>
+<br>
 Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const {<br>
   QualType type(this, 0);<br>
   do {<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>