Clang Project

clang_source_code/lib/AST/Linkage.h
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides AST-internal utilities for linkage and visibility
10// calculation.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
15#define LLVM_CLANG_LIB_AST_LINKAGE_H
16
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Type.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/Optional.h"
22#include "llvm/ADT/PointerIntPair.h"
23
24namespace clang {
25/// Kinds of LV computation.  The linkage side of the computation is
26/// always the same, but different things can change how visibility is
27/// computed.
28struct LVComputationKind {
29  /// The kind of entity whose visibility is ultimately being computed;
30  /// visibility computations for types and non-types follow different rules.
31  unsigned ExplicitKind : 1;
32  /// Whether explicit visibility attributes should be ignored. When set,
33  /// visibility may only be restricted by the visibility of template arguments.
34  unsigned IgnoreExplicitVisibility : 1;
35  /// Whether all visibility should be ignored. When set, we're only interested
36  /// in computing linkage.
37  unsigned IgnoreAllVisibility : 1;
38
39  enum { NumLVComputationKindBits = 3 };
40
41  explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
42      : ExplicitKind(EK), IgnoreExplicitVisibility(false),
43        IgnoreAllVisibility(false) {}
44
45  NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
46    return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
47  }
48
49  bool isTypeVisibility() const {
50    return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
51  }
52  bool isValueVisibility() const {
53    return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
54  }
55
56  /// Do an LV computation when we only care about the linkage.
57  static LVComputationKind forLinkageOnly() {
58    LVComputationKind Result(NamedDecl::VisibilityForValue);
59    Result.IgnoreExplicitVisibility = true;
60    Result.IgnoreAllVisibility = true;
61    return Result;
62  }
63
64  unsigned toBits() {
65    unsigned Bits = 0;
66    Bits = (Bits << 1) | ExplicitKind;
67    Bits = (Bits << 1) | IgnoreExplicitVisibility;
68    Bits = (Bits << 1) | IgnoreAllVisibility;
69    return Bits;
70  }
71};
72
73class LinkageComputer {
74  // We have a cache for repeated linkage/visibility computations. This saves us
75  // from exponential behavior in heavily templated code, such as:
76  //
77  // template <typename T, typename V> struct {};
78  // using A = int;
79  // using B = Foo<A, A>;
80  // using C = Foo<B, B>;
81  // using D = Foo<C, C>;
82  //
83  // The integer represents an LVComputationKind.
84  using QueryType =
85      llvm::PointerIntPair<const NamedDecl *,
86                           LVComputationKind::NumLVComputationKindBits>;
87  llvm::SmallDenseMap<QueryType, LinkageInfo, 8CachedLinkageInfo;
88
89  static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
90    return QueryType(NDKind.toBits());
91  }
92
93  llvm::Optional<LinkageInfolookup(const NamedDecl *ND,
94                                     LVComputationKind Kindconst {
95    auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
96    if (Iter == CachedLinkageInfo.end())
97      return None;
98    return Iter->second;
99  }
100
101  void cache(const NamedDecl *NDLVComputationKind KindLinkageInfo Info) {
102    CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
103  }
104
105  LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgumentArgs,
106                                           LVComputationKind computation);
107
108  LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
109                                           LVComputationKind computation);
110
111  void mergeTemplateLV(LinkageInfo &LVconst FunctionDecl *fn,
112                       const FunctionTemplateSpecializationInfo *specInfo,
113                       LVComputationKind computation);
114
115  void mergeTemplateLV(LinkageInfo &LV,
116                       const ClassTemplateSpecializationDecl *spec,
117                       LVComputationKind computation);
118
119  void mergeTemplateLV(LinkageInfo &LV,
120                       const VarTemplateSpecializationDecl *spec,
121                       LVComputationKind computation);
122
123  LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
124                                         LVComputationKind computation,
125                                         bool IgnoreVarTypeLinkage);
126
127  LinkageInfo getLVForClassMember(const NamedDecl *D,
128                                  LVComputationKind computation,
129                                  bool IgnoreVarTypeLinkage);
130
131  LinkageInfo getLVForClosure(const DeclContext *DCDecl *ContextDecl,
132                              LVComputationKind computation);
133
134  LinkageInfo getLVForLocalDecl(const NamedDecl *D,
135                                LVComputationKind computation);
136
137  LinkageInfo getLVForType(const Type &TLVComputationKind computation);
138
139  LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
140                                            LVComputationKind computation);
141
142public:
143  LinkageInfo computeLVForDecl(const NamedDecl *D,
144                               LVComputationKind computation,
145                               bool IgnoreVarTypeLinkage = false);
146
147  LinkageInfo getLVForDecl(const NamedDecl *DLVComputationKind computation);
148
149  LinkageInfo computeTypeLinkageInfo(const Type *T);
150  LinkageInfo computeTypeLinkageInfo(QualType T) {
151    return computeTypeLinkageInfo(T.getTypePtr());
152  }
153
154  LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
155
156  LinkageInfo getTypeLinkageAndVisibility(const Type *T);
157  LinkageInfo getTypeLinkageAndVisibility(QualType T) {
158    return getTypeLinkageAndVisibility(T.getTypePtr());
159  }
160};
161// namespace clang
162
163#endif
164
clang::LVComputationKind::ExplicitKind
clang::LVComputationKind::IgnoreExplicitVisibility
clang::LVComputationKind::IgnoreAllVisibility
clang::LVComputationKind::getExplicitVisibilityKind
clang::LVComputationKind::isTypeVisibility
clang::LVComputationKind::isValueVisibility
clang::LVComputationKind::forLinkageOnly
clang::LVComputationKind::toBits
clang::LinkageComputer::CachedLinkageInfo
clang::LinkageComputer::makeCacheKey
clang::LinkageComputer::lookup
clang::LinkageComputer::cache
clang::LinkageComputer::getLVForTemplateArgumentList
clang::LinkageComputer::getLVForTemplateArgumentList
clang::LinkageComputer::mergeTemplateLV
clang::LinkageComputer::mergeTemplateLV
clang::LinkageComputer::getLVForNamespaceScopeDecl
clang::LinkageComputer::getLVForClassMember
clang::LinkageComputer::getLVForClosure
clang::LinkageComputer::getLVForLocalDecl
clang::LinkageComputer::getLVForType
clang::LinkageComputer::getLVForTemplateParameterList
clang::LinkageComputer::computeLVForDecl
clang::LinkageComputer::getLVForDecl
clang::LinkageComputer::computeTypeLinkageInfo
clang::LinkageComputer::computeTypeLinkageInfo
clang::LinkageComputer::getDeclLinkageAndVisibility
clang::LinkageComputer::getTypeLinkageAndVisibility
clang::LinkageComputer::getTypeLinkageAndVisibility