<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>