blob: 4e913540de86f75fb34e0f7b6df884124643d699 [file] [log] [blame]
George Burgess IV99db3ea2017-08-09 04:02:49 +00001//===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
George Burgess IV99db3ea2017-08-09 04:02:49 +00006//
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"
George Burgess IV35cb4f82017-08-09 04:12:17 +000021#include "llvm/ADT/Optional.h"
Bruno Riccicf86ce02018-09-25 13:43:25 +000022#include "llvm/ADT/PointerIntPair.h"
George Burgess IV99db3ea2017-08-09 04:02:49 +000023
24namespace clang {
George Burgess IV99db3ea2017-08-09 04:02:49 +000025/// 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.
Richard Smithfbe7b462017-09-22 02:22:32 +000028struct 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;
George Burgess IV99db3ea2017-08-09 04:02:49 +000038
Bruno Riccicf86ce02018-09-25 13:43:25 +000039 enum { NumLVComputationKindBits = 3 };
40
Richard Smithfbe7b462017-09-22 02:22:32 +000041 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
42 : ExplicitKind(EK), IgnoreExplicitVisibility(false),
43 IgnoreAllVisibility(false) {}
George Burgess IV99db3ea2017-08-09 04:02:49 +000044
Richard Smithfbe7b462017-09-22 02:22:32 +000045 NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
46 return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
47 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000048
Richard Smithfbe7b462017-09-22 02:22:32 +000049 bool isTypeVisibility() const {
50 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
51 }
52 bool isValueVisibility() const {
53 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
54 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000055
56 /// Do an LV computation when we only care about the linkage.
Richard Smithfbe7b462017-09-22 02:22:32 +000057 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 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000071};
72
73class LinkageComputer {
George Burgess IV35cb4f82017-08-09 04:12:17 +000074 // 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>;
George Burgess IVb8709ba2017-08-09 21:20:41 +000082 //
Bruno Riccicf86ce02018-09-25 13:43:25 +000083 // The integer represents an LVComputationKind.
84 using QueryType =
85 llvm::PointerIntPair<const NamedDecl *,
86 LVComputationKind::NumLVComputationKindBits>;
George Burgess IV35cb4f82017-08-09 04:12:17 +000087 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
George Burgess IVb8709ba2017-08-09 21:20:41 +000088
89 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
Bruno Riccicf86ce02018-09-25 13:43:25 +000090 return QueryType(ND, Kind.toBits());
George Burgess IVb8709ba2017-08-09 21:20:41 +000091 }
92
George Burgess IV35cb4f82017-08-09 04:12:17 +000093 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
94 LVComputationKind Kind) const {
George Burgess IVb8709ba2017-08-09 21:20:41 +000095 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
George Burgess IV35cb4f82017-08-09 04:12:17 +000096 if (Iter == CachedLinkageInfo.end())
97 return None;
98 return Iter->second;
99 }
100
101 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
George Burgess IVb8709ba2017-08-09 21:20:41 +0000102 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
George Burgess IV35cb4f82017-08-09 04:12:17 +0000103 }
104
George Burgess IV99db3ea2017-08-09 04:02:49 +0000105 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
106 LVComputationKind computation);
107
108 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
109 LVComputationKind computation);
110
111 void mergeTemplateLV(LinkageInfo &LV, const 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,
Richard Smithc95d2c52017-09-22 04:25:05 +0000124 LVComputationKind computation,
125 bool IgnoreVarTypeLinkage);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000126
127 LinkageInfo getLVForClassMember(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000128 LVComputationKind computation,
129 bool IgnoreVarTypeLinkage);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000130
131 LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
132 LVComputationKind computation);
133
134 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
135 LVComputationKind computation);
136
137 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
138
139 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
140 LVComputationKind computation);
141
142public:
143 LinkageInfo computeLVForDecl(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000144 LVComputationKind computation,
145 bool IgnoreVarTypeLinkage = false);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000146
147 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind 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