blob: 8ad748bcc4a26bbd1ab41ad97326a4f0ac98835b [file] [log] [blame]
George Burgess IV99db3ea2017-08-09 04:02:49 +00001//===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides AST-internal utilities for linkage and visibility
11// calculation.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
16#define LLVM_CLANG_LIB_AST_LINKAGE_H
17
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/Type.h"
21#include "llvm/ADT/DenseMap.h"
George Burgess IV35cb4f82017-08-09 04:12:17 +000022#include "llvm/ADT/Optional.h"
Bruno Riccicf86ce02018-09-25 13:43:25 +000023#include "llvm/ADT/PointerIntPair.h"
George Burgess IV99db3ea2017-08-09 04:02:49 +000024
25namespace clang {
George Burgess IV99db3ea2017-08-09 04:02:49 +000026/// 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.
Richard Smithfbe7b462017-09-22 02:22:32 +000029struct 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;
George Burgess IV99db3ea2017-08-09 04:02:49 +000039
Bruno Riccicf86ce02018-09-25 13:43:25 +000040 enum { NumLVComputationKindBits = 3 };
41
Richard Smithfbe7b462017-09-22 02:22:32 +000042 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
43 : ExplicitKind(EK), IgnoreExplicitVisibility(false),
44 IgnoreAllVisibility(false) {}
George Burgess IV99db3ea2017-08-09 04:02:49 +000045
Richard Smithfbe7b462017-09-22 02:22:32 +000046 NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
47 return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
48 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000049
Richard Smithfbe7b462017-09-22 02:22:32 +000050 bool isTypeVisibility() const {
51 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
52 }
53 bool isValueVisibility() const {
54 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
55 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000056
57 /// Do an LV computation when we only care about the linkage.
Richard Smithfbe7b462017-09-22 02:22:32 +000058 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 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000072};
73
74class LinkageComputer {
George Burgess IV35cb4f82017-08-09 04:12:17 +000075 // 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>;
George Burgess IVb8709ba2017-08-09 21:20:41 +000083 //
Bruno Riccicf86ce02018-09-25 13:43:25 +000084 // The integer represents an LVComputationKind.
85 using QueryType =
86 llvm::PointerIntPair<const NamedDecl *,
87 LVComputationKind::NumLVComputationKindBits>;
George Burgess IV35cb4f82017-08-09 04:12:17 +000088 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
George Burgess IVb8709ba2017-08-09 21:20:41 +000089
90 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
Bruno Riccicf86ce02018-09-25 13:43:25 +000091 return QueryType(ND, Kind.toBits());
George Burgess IVb8709ba2017-08-09 21:20:41 +000092 }
93
George Burgess IV35cb4f82017-08-09 04:12:17 +000094 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
95 LVComputationKind Kind) const {
George Burgess IVb8709ba2017-08-09 21:20:41 +000096 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
George Burgess IV35cb4f82017-08-09 04:12:17 +000097 if (Iter == CachedLinkageInfo.end())
98 return None;
99 return Iter->second;
100 }
101
102 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
George Burgess IVb8709ba2017-08-09 21:20:41 +0000103 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
George Burgess IV35cb4f82017-08-09 04:12:17 +0000104 }
105
George Burgess IV99db3ea2017-08-09 04:02:49 +0000106 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,
Richard Smithc95d2c52017-09-22 04:25:05 +0000125 LVComputationKind computation,
126 bool IgnoreVarTypeLinkage);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000127
128 LinkageInfo getLVForClassMember(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000129 LVComputationKind computation,
130 bool IgnoreVarTypeLinkage);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000131
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
143public:
144 LinkageInfo computeLVForDecl(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000145 LVComputationKind computation,
146 bool IgnoreVarTypeLinkage = false);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000147
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