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