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/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"
25 /// Kinds of LV computation. The linkage side of the computation is
26 /// always the same, but different things can change how visibility is
28 struct 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;
39 enum { NumLVComputationKindBits = 3 };
41 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
42 : ExplicitKind(EK), IgnoreExplicitVisibility(false),
43 IgnoreAllVisibility(false) {}
45 NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
46 return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
49 bool isTypeVisibility() const {
50 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
52 bool isValueVisibility() const {
53 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
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;
66 Bits = (Bits << 1) | ExplicitKind;
67 Bits = (Bits << 1) | IgnoreExplicitVisibility;
68 Bits = (Bits << 1) | IgnoreAllVisibility;
73 class LinkageComputer {
74 // We have a cache for repeated linkage/visibility computations. This saves us
75 // from exponential behavior in heavily templated code, such as:
77 // template <typename T, typename V> struct {};
79 // using B = Foo<A, A>;
80 // using C = Foo<B, B>;
81 // using D = Foo<C, C>;
83 // The integer represents an LVComputationKind.
85 llvm::PointerIntPair<const NamedDecl *,
86 LVComputationKind::NumLVComputationKindBits>;
87 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
89 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
90 return QueryType(ND, Kind.toBits());
93 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
94 LVComputationKind Kind) const {
95 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
96 if (Iter == CachedLinkageInfo.end())
101 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
102 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
105 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
106 LVComputationKind computation);
108 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
109 LVComputationKind computation);
111 void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
112 const FunctionTemplateSpecializationInfo *specInfo,
113 LVComputationKind computation);
115 void mergeTemplateLV(LinkageInfo &LV,
116 const ClassTemplateSpecializationDecl *spec,
117 LVComputationKind computation);
119 void mergeTemplateLV(LinkageInfo &LV,
120 const VarTemplateSpecializationDecl *spec,
121 LVComputationKind computation);
123 LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
124 LVComputationKind computation,
125 bool IgnoreVarTypeLinkage);
127 LinkageInfo getLVForClassMember(const NamedDecl *D,
128 LVComputationKind computation,
129 bool IgnoreVarTypeLinkage);
131 LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
132 LVComputationKind computation);
134 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
135 LVComputationKind computation);
137 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
139 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
140 LVComputationKind computation);
143 LinkageInfo computeLVForDecl(const NamedDecl *D,
144 LVComputationKind computation,
145 bool IgnoreVarTypeLinkage = false);
147 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
149 LinkageInfo computeTypeLinkageInfo(const Type *T);
150 LinkageInfo computeTypeLinkageInfo(QualType T) {
151 return computeTypeLinkageInfo(T.getTypePtr());
154 LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
156 LinkageInfo getTypeLinkageAndVisibility(const Type *T);
157 LinkageInfo getTypeLinkageAndVisibility(QualType T) {
158 return getTypeLinkageAndVisibility(T.getTypePtr());