annotate clang/lib/AST/Linkage.h @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 1d019706d866
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // This file provides AST-internal utilities for linkage and visibility
anatofuz
parents:
diff changeset
10 // calculation.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
anatofuz
parents:
diff changeset
15 #define LLVM_CLANG_LIB_AST_LINKAGE_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 #include "clang/AST/ASTFwd.h"
anatofuz
parents:
diff changeset
18 #include "clang/AST/Decl.h"
anatofuz
parents:
diff changeset
19 #include "clang/AST/DeclCXX.h"
anatofuz
parents:
diff changeset
20 #include "clang/AST/Type.h"
anatofuz
parents:
diff changeset
21 #include "llvm/ADT/DenseMap.h"
anatofuz
parents:
diff changeset
22 #include "llvm/ADT/Optional.h"
anatofuz
parents:
diff changeset
23 #include "llvm/ADT/PointerIntPair.h"
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 namespace clang {
anatofuz
parents:
diff changeset
26 /// Kinds of LV computation. The linkage side of the computation is
anatofuz
parents:
diff changeset
27 /// always the same, but different things can change how visibility is
anatofuz
parents:
diff changeset
28 /// computed.
anatofuz
parents:
diff changeset
29 struct LVComputationKind {
anatofuz
parents:
diff changeset
30 /// The kind of entity whose visibility is ultimately being computed;
anatofuz
parents:
diff changeset
31 /// visibility computations for types and non-types follow different rules.
anatofuz
parents:
diff changeset
32 unsigned ExplicitKind : 1;
anatofuz
parents:
diff changeset
33 /// Whether explicit visibility attributes should be ignored. When set,
anatofuz
parents:
diff changeset
34 /// visibility may only be restricted by the visibility of template arguments.
anatofuz
parents:
diff changeset
35 unsigned IgnoreExplicitVisibility : 1;
anatofuz
parents:
diff changeset
36 /// Whether all visibility should be ignored. When set, we're only interested
anatofuz
parents:
diff changeset
37 /// in computing linkage.
anatofuz
parents:
diff changeset
38 unsigned IgnoreAllVisibility : 1;
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 enum { NumLVComputationKindBits = 3 };
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
anatofuz
parents:
diff changeset
43 : ExplicitKind(EK), IgnoreExplicitVisibility(false),
anatofuz
parents:
diff changeset
44 IgnoreAllVisibility(false) {}
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
anatofuz
parents:
diff changeset
47 return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
anatofuz
parents:
diff changeset
48 }
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 bool isTypeVisibility() const {
anatofuz
parents:
diff changeset
51 return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
anatofuz
parents:
diff changeset
52 }
anatofuz
parents:
diff changeset
53 bool isValueVisibility() const {
anatofuz
parents:
diff changeset
54 return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 /// Do an LV computation when we only care about the linkage.
anatofuz
parents:
diff changeset
58 static LVComputationKind forLinkageOnly() {
anatofuz
parents:
diff changeset
59 LVComputationKind Result(NamedDecl::VisibilityForValue);
anatofuz
parents:
diff changeset
60 Result.IgnoreExplicitVisibility = true;
anatofuz
parents:
diff changeset
61 Result.IgnoreAllVisibility = true;
anatofuz
parents:
diff changeset
62 return Result;
anatofuz
parents:
diff changeset
63 }
anatofuz
parents:
diff changeset
64
anatofuz
parents:
diff changeset
65 unsigned toBits() {
anatofuz
parents:
diff changeset
66 unsigned Bits = 0;
anatofuz
parents:
diff changeset
67 Bits = (Bits << 1) | ExplicitKind;
anatofuz
parents:
diff changeset
68 Bits = (Bits << 1) | IgnoreExplicitVisibility;
anatofuz
parents:
diff changeset
69 Bits = (Bits << 1) | IgnoreAllVisibility;
anatofuz
parents:
diff changeset
70 return Bits;
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72 };
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 class LinkageComputer {
anatofuz
parents:
diff changeset
75 // We have a cache for repeated linkage/visibility computations. This saves us
anatofuz
parents:
diff changeset
76 // from exponential behavior in heavily templated code, such as:
anatofuz
parents:
diff changeset
77 //
anatofuz
parents:
diff changeset
78 // template <typename T, typename V> struct {};
anatofuz
parents:
diff changeset
79 // using A = int;
anatofuz
parents:
diff changeset
80 // using B = Foo<A, A>;
anatofuz
parents:
diff changeset
81 // using C = Foo<B, B>;
anatofuz
parents:
diff changeset
82 // using D = Foo<C, C>;
anatofuz
parents:
diff changeset
83 //
anatofuz
parents:
diff changeset
84 // The integer represents an LVComputationKind.
anatofuz
parents:
diff changeset
85 using QueryType =
anatofuz
parents:
diff changeset
86 llvm::PointerIntPair<const NamedDecl *,
anatofuz
parents:
diff changeset
87 LVComputationKind::NumLVComputationKindBits>;
anatofuz
parents:
diff changeset
88 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
anatofuz
parents:
diff changeset
89
anatofuz
parents:
diff changeset
90 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
anatofuz
parents:
diff changeset
91 return QueryType(ND, Kind.toBits());
anatofuz
parents:
diff changeset
92 }
anatofuz
parents:
diff changeset
93
anatofuz
parents:
diff changeset
94 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
anatofuz
parents:
diff changeset
95 LVComputationKind Kind) const {
anatofuz
parents:
diff changeset
96 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
anatofuz
parents:
diff changeset
97 if (Iter == CachedLinkageInfo.end())
anatofuz
parents:
diff changeset
98 return None;
anatofuz
parents:
diff changeset
99 return Iter->second;
anatofuz
parents:
diff changeset
100 }
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
anatofuz
parents:
diff changeset
103 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
anatofuz
parents:
diff changeset
104 }
anatofuz
parents:
diff changeset
105
anatofuz
parents:
diff changeset
106 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
anatofuz
parents:
diff changeset
107 LVComputationKind computation);
anatofuz
parents:
diff changeset
108
anatofuz
parents:
diff changeset
109 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
anatofuz
parents:
diff changeset
110 LVComputationKind computation);
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
anatofuz
parents:
diff changeset
113 const FunctionTemplateSpecializationInfo *specInfo,
anatofuz
parents:
diff changeset
114 LVComputationKind computation);
anatofuz
parents:
diff changeset
115
anatofuz
parents:
diff changeset
116 void mergeTemplateLV(LinkageInfo &LV,
anatofuz
parents:
diff changeset
117 const ClassTemplateSpecializationDecl *spec,
anatofuz
parents:
diff changeset
118 LVComputationKind computation);
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 void mergeTemplateLV(LinkageInfo &LV,
anatofuz
parents:
diff changeset
121 const VarTemplateSpecializationDecl *spec,
anatofuz
parents:
diff changeset
122 LVComputationKind computation);
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
anatofuz
parents:
diff changeset
125 LVComputationKind computation,
anatofuz
parents:
diff changeset
126 bool IgnoreVarTypeLinkage);
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 LinkageInfo getLVForClassMember(const NamedDecl *D,
anatofuz
parents:
diff changeset
129 LVComputationKind computation,
anatofuz
parents:
diff changeset
130 bool IgnoreVarTypeLinkage);
anatofuz
parents:
diff changeset
131
anatofuz
parents:
diff changeset
132 LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
anatofuz
parents:
diff changeset
133 LVComputationKind computation);
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
anatofuz
parents:
diff changeset
136 LVComputationKind computation);
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
anatofuz
parents:
diff changeset
141 LVComputationKind computation);
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 public:
anatofuz
parents:
diff changeset
144 LinkageInfo computeLVForDecl(const NamedDecl *D,
anatofuz
parents:
diff changeset
145 LVComputationKind computation,
anatofuz
parents:
diff changeset
146 bool IgnoreVarTypeLinkage = false);
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 LinkageInfo computeTypeLinkageInfo(const Type *T);
anatofuz
parents:
diff changeset
151 LinkageInfo computeTypeLinkageInfo(QualType T) {
anatofuz
parents:
diff changeset
152 return computeTypeLinkageInfo(T.getTypePtr());
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
anatofuz
parents:
diff changeset
156
anatofuz
parents:
diff changeset
157 LinkageInfo getTypeLinkageAndVisibility(const Type *T);
anatofuz
parents:
diff changeset
158 LinkageInfo getTypeLinkageAndVisibility(QualType T) {
anatofuz
parents:
diff changeset
159 return getTypeLinkageAndVisibility(T.getTypePtr());
anatofuz
parents:
diff changeset
160 }
anatofuz
parents:
diff changeset
161 };
anatofuz
parents:
diff changeset
162 } // namespace clang
anatofuz
parents:
diff changeset
163
anatofuz
parents:
diff changeset
164 #endif