brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 4aaf0c9 Raw
170 lines · c
1//===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file provides AST-internal utilities for linkage and visibility10// calculation.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_CLANG_LIB_AST_LINKAGE_H15#define LLVM_CLANG_LIB_AST_LINKAGE_H16 17#include "clang/AST/ASTFwd.h"18#include "clang/AST/Decl.h"19#include "clang/AST/DeclCXX.h"20#include "clang/AST/Type.h"21#include "llvm/ADT/DenseMap.h"22#include "llvm/ADT/PointerIntPair.h"23#include <optional>24 25namespace clang {26/// Kinds of LV computation.  The linkage side of the computation is27/// always the same, but different things can change how visibility is28/// computed.29struct LVComputationKind {30  /// The kind of entity whose visibility is ultimately being computed;31  /// visibility computations for types and non-types follow different rules.32  LLVM_PREFERRED_TYPE(bool)33  unsigned ExplicitKind : 1;34  /// Whether explicit visibility attributes should be ignored. When set,35  /// visibility may only be restricted by the visibility of template arguments.36  LLVM_PREFERRED_TYPE(bool)37  unsigned IgnoreExplicitVisibility : 1;38  /// Whether all visibility should be ignored. When set, we're only interested39  /// in computing linkage.40  LLVM_PREFERRED_TYPE(bool)41  unsigned IgnoreAllVisibility : 1;42 43  static constexpr int NumLVComputationKindBits = 3;44 45  explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)46      : ExplicitKind(EK), IgnoreExplicitVisibility(false),47        IgnoreAllVisibility(false) {}48 49  NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {50    return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);51  }52 53  bool isTypeVisibility() const {54    return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;55  }56  bool isValueVisibility() const {57    return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;58  }59 60  /// Do an LV computation when we only care about the linkage.61  static LVComputationKind forLinkageOnly() {62    LVComputationKind Result(NamedDecl::VisibilityForValue);63    Result.IgnoreExplicitVisibility = true;64    Result.IgnoreAllVisibility = true;65    return Result;66  }67 68  unsigned toBits() {69    unsigned Bits = 0;70    Bits = (Bits << 1) | ExplicitKind;71    Bits = (Bits << 1) | IgnoreExplicitVisibility;72    Bits = (Bits << 1) | IgnoreAllVisibility;73    return Bits;74  }75};76 77class LinkageComputer {78  // We have a cache for repeated linkage/visibility computations. This saves us79  // from exponential behavior in heavily templated code, such as:80  //81  // template <typename T, typename V> struct {};82  // using A = int;83  // using B = Foo<A, A>;84  // using C = Foo<B, B>;85  // using D = Foo<C, C>;86  //87  // The integer represents an LVComputationKind.88  using QueryType =89      llvm::PointerIntPair<const NamedDecl *,90                           LVComputationKind::NumLVComputationKindBits>;91  llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;92 93  static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {94    return QueryType(ND, Kind.toBits());95  }96 97  std::optional<LinkageInfo> lookup(const NamedDecl *ND,98                                    LVComputationKind Kind) const {99    auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));100    if (Iter == CachedLinkageInfo.end())101      return std::nullopt;102    return Iter->second;103  }104 105  void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {106    CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;107  }108 109  LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,110                                           LVComputationKind computation);111 112  LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,113                                           LVComputationKind computation);114 115  void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,116                       const FunctionTemplateSpecializationInfo *specInfo,117                       LVComputationKind computation);118 119  void mergeTemplateLV(LinkageInfo &LV,120                       const ClassTemplateSpecializationDecl *spec,121                       LVComputationKind computation);122 123  void mergeTemplateLV(LinkageInfo &LV,124                       const VarTemplateSpecializationDecl *spec,125                       LVComputationKind computation);126 127  LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,128                                         LVComputationKind computation,129                                         bool IgnoreVarTypeLinkage);130 131  LinkageInfo getLVForClassMember(const NamedDecl *D,132                                  LVComputationKind computation,133                                  bool IgnoreVarTypeLinkage);134 135  LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,136                              LVComputationKind computation);137 138  LinkageInfo getLVForLocalDecl(const NamedDecl *D,139                                LVComputationKind computation);140 141  LinkageInfo getLVForType(const Type &T, LVComputationKind computation);142 143  LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,144                                            LVComputationKind computation);145 146  LinkageInfo getLVForValue(const APValue &V, LVComputationKind computation);147 148public:149  LinkageInfo computeLVForDecl(const NamedDecl *D,150                               LVComputationKind computation,151                               bool IgnoreVarTypeLinkage = false);152 153  LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);154 155  LinkageInfo computeTypeLinkageInfo(const Type *T);156  LinkageInfo computeTypeLinkageInfo(QualType T) {157    return computeTypeLinkageInfo(T.getTypePtr());158  }159 160  LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);161 162  LinkageInfo getTypeLinkageAndVisibility(const Type *T);163  LinkageInfo getTypeLinkageAndVisibility(QualType T) {164    return getTypeLinkageAndVisibility(T.getTypePtr());165  }166};167} // namespace clang168 169#endif170