1 //===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides AST-internal utilities for linkage and visibility
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
15 #define LLVM_CLANG_LIB_AST_LINKAGE_H
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"
26 /// Kinds of LV computation. The linkage side of the computation is
27 /// always the same, but different things can change how visibility is
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;
40 enum { NumLVComputationKindBits
= 3 };
42 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK
)
43 : ExplicitKind(EK
), IgnoreExplicitVisibility(false),
44 IgnoreAllVisibility(false) {}
46 NamedDecl::ExplicitVisibilityKind
getExplicitVisibilityKind() const {
47 return static_cast<NamedDecl::ExplicitVisibilityKind
>(ExplicitKind
);
50 bool isTypeVisibility() const {
51 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType
;
53 bool isValueVisibility() const {
54 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue
;
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;
67 Bits
= (Bits
<< 1) | ExplicitKind
;
68 Bits
= (Bits
<< 1) | IgnoreExplicitVisibility
;
69 Bits
= (Bits
<< 1) | IgnoreAllVisibility
;
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:
78 // template <typename T, typename V> struct {};
80 // using B = Foo<A, A>;
81 // using C = Foo<B, B>;
82 // using D = Foo<C, C>;
84 // The integer represents an LVComputationKind.
86 llvm::PointerIntPair
<const NamedDecl
*,
87 LVComputationKind::NumLVComputationKindBits
>;
88 llvm::SmallDenseMap
<QueryType
, LinkageInfo
, 8> CachedLinkageInfo
;
90 static QueryType
makeCacheKey(const NamedDecl
*ND
, LVComputationKind Kind
) {
91 return QueryType(ND
, Kind
.toBits());
94 std::optional
<LinkageInfo
> lookup(const NamedDecl
*ND
,
95 LVComputationKind Kind
) const {
96 auto Iter
= CachedLinkageInfo
.find(makeCacheKey(ND
, Kind
));
97 if (Iter
== CachedLinkageInfo
.end())
102 void cache(const NamedDecl
*ND
, LVComputationKind Kind
, LinkageInfo Info
) {
103 CachedLinkageInfo
[makeCacheKey(ND
, Kind
)] = Info
;
106 LinkageInfo
getLVForTemplateArgumentList(ArrayRef
<TemplateArgument
> Args
,
107 LVComputationKind computation
);
109 LinkageInfo
getLVForTemplateArgumentList(const TemplateArgumentList
&TArgs
,
110 LVComputationKind computation
);
112 void mergeTemplateLV(LinkageInfo
&LV
, const FunctionDecl
*fn
,
113 const FunctionTemplateSpecializationInfo
*specInfo
,
114 LVComputationKind computation
);
116 void mergeTemplateLV(LinkageInfo
&LV
,
117 const ClassTemplateSpecializationDecl
*spec
,
118 LVComputationKind computation
);
120 void mergeTemplateLV(LinkageInfo
&LV
,
121 const VarTemplateSpecializationDecl
*spec
,
122 LVComputationKind computation
);
124 LinkageInfo
getLVForNamespaceScopeDecl(const NamedDecl
*D
,
125 LVComputationKind computation
,
126 bool IgnoreVarTypeLinkage
);
128 LinkageInfo
getLVForClassMember(const NamedDecl
*D
,
129 LVComputationKind computation
,
130 bool IgnoreVarTypeLinkage
);
132 LinkageInfo
getLVForClosure(const DeclContext
*DC
, Decl
*ContextDecl
,
133 LVComputationKind computation
);
135 LinkageInfo
getLVForLocalDecl(const NamedDecl
*D
,
136 LVComputationKind computation
);
138 LinkageInfo
getLVForType(const Type
&T
, LVComputationKind computation
);
140 LinkageInfo
getLVForTemplateParameterList(const TemplateParameterList
*Params
,
141 LVComputationKind computation
);
143 LinkageInfo
getLVForValue(const APValue
&V
, LVComputationKind computation
);
146 LinkageInfo
computeLVForDecl(const NamedDecl
*D
,
147 LVComputationKind computation
,
148 bool IgnoreVarTypeLinkage
= false);
150 LinkageInfo
getLVForDecl(const NamedDecl
*D
, LVComputationKind computation
);
152 LinkageInfo
computeTypeLinkageInfo(const Type
*T
);
153 LinkageInfo
computeTypeLinkageInfo(QualType T
) {
154 return computeTypeLinkageInfo(T
.getTypePtr());
157 LinkageInfo
getDeclLinkageAndVisibility(const NamedDecl
*D
);
159 LinkageInfo
getTypeLinkageAndVisibility(const Type
*T
);
160 LinkageInfo
getTypeLinkageAndVisibility(QualType T
) {
161 return getTypeLinkageAndVisibility(T
.getTypePtr());