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

George Burgess IV via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 15:24:39 PDT 2017


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