blob: e6489c7ef2b3132a54495c0116693bbb8514a1ac [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"
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
Richard Smithfbe7b462017-09-22 02:22:32 +000039 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
40 : ExplicitKind(EK), IgnoreExplicitVisibility(false),
41 IgnoreAllVisibility(false) {}
George Burgess IV99db3ea2017-08-09 04:02:49 +000042
Richard Smithfbe7b462017-09-22 02:22:32 +000043 NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
44 return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
45 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000046
Richard Smithfbe7b462017-09-22 02:22:32 +000047 bool isTypeVisibility() const {
48 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
49 }
50 bool isValueVisibility() const {
51 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
52 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000053
54 /// Do an LV computation when we only care about the linkage.
Richard Smithfbe7b462017-09-22 02:22:32 +000055 static LVComputationKind forLinkageOnly() {
56 LVComputationKind Result(NamedDecl::VisibilityForValue);
57 Result.IgnoreExplicitVisibility = true;
58 Result.IgnoreAllVisibility = true;
59 return Result;
60 }
61
62 unsigned toBits() {
63 unsigned Bits = 0;
64 Bits = (Bits << 1) | ExplicitKind;
65 Bits = (Bits << 1) | IgnoreExplicitVisibility;
66 Bits = (Bits << 1) | IgnoreAllVisibility;
67 return Bits;
68 }
George Burgess IV99db3ea2017-08-09 04:02:49 +000069};
70
71class LinkageComputer {
George Burgess IV35cb4f82017-08-09 04:12:17 +000072 // We have a cache for repeated linkage/visibility computations. This saves us
73 // from exponential behavior in heavily templated code, such as:
74 //
75 // template <typename T, typename V> struct {};
76 // using A = int;
77 // using B = Foo<A, A>;
78 // using C = Foo<B, B>;
79 // using D = Foo<C, C>;
George Burgess IVb8709ba2017-08-09 21:20:41 +000080 //
Richard Smithfbe7b462017-09-22 02:22:32 +000081 // The unsigned represents an LVComputationKind.
George Burgess IVb8709ba2017-08-09 21:20:41 +000082 using QueryType = std::pair<const NamedDecl *, unsigned>;
George Burgess IV35cb4f82017-08-09 04:12:17 +000083 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
George Burgess IVb8709ba2017-08-09 21:20:41 +000084
85 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
Richard Smithfbe7b462017-09-22 02:22:32 +000086 return std::make_pair(ND, Kind.toBits());
George Burgess IVb8709ba2017-08-09 21:20:41 +000087 }
88
George Burgess IV35cb4f82017-08-09 04:12:17 +000089 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
90 LVComputationKind Kind) const {
George Burgess IVb8709ba2017-08-09 21:20:41 +000091 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
George Burgess IV35cb4f82017-08-09 04:12:17 +000092 if (Iter == CachedLinkageInfo.end())
93 return None;
94 return Iter->second;
95 }
96
97 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
George Burgess IVb8709ba2017-08-09 21:20:41 +000098 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
George Burgess IV35cb4f82017-08-09 04:12:17 +000099 }
100
George Burgess IV99db3ea2017-08-09 04:02:49 +0000101 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
102 LVComputationKind computation);
103
104 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
105 LVComputationKind computation);
106
107 void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
108 const FunctionTemplateSpecializationInfo *specInfo,
109 LVComputationKind computation);
110
111 void mergeTemplateLV(LinkageInfo &LV,
112 const ClassTemplateSpecializationDecl *spec,
113 LVComputationKind computation);
114
115 void mergeTemplateLV(LinkageInfo &LV,
116 const VarTemplateSpecializationDecl *spec,
117 LVComputationKind computation);
118
119 LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000120 LVComputationKind computation,
121 bool IgnoreVarTypeLinkage);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000122
123 LinkageInfo getLVForClassMember(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 getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
128 LVComputationKind computation);
129
130 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
131 LVComputationKind computation);
132
133 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
134
135 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
136 LVComputationKind computation);
137
138public:
139 LinkageInfo computeLVForDecl(const NamedDecl *D,
Richard Smithc95d2c52017-09-22 04:25:05 +0000140 LVComputationKind computation,
141 bool IgnoreVarTypeLinkage = false);
George Burgess IV99db3ea2017-08-09 04:02:49 +0000142
143 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
144
145 LinkageInfo computeTypeLinkageInfo(const Type *T);
146 LinkageInfo computeTypeLinkageInfo(QualType T) {
147 return computeTypeLinkageInfo(T.getTypePtr());
148 }
149
150 LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
151
152 LinkageInfo getTypeLinkageAndVisibility(const Type *T);
153 LinkageInfo getTypeLinkageAndVisibility(QualType T) {
154 return getTypeLinkageAndVisibility(T.getTypePtr());
155 }
156};
157} // namespace clang
158
159#endif