r310436 - [AST] Move visibility computations into a class; NFC

George Burgess IV via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 16:10:03 PDT 2017


Okay, apparently release_capability doesn't work how I assumed, so it
looks like this may be a bug in r310403. Pinged that thread.

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


More information about the cfe-commits mailing list