]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/AST/Linkage.h
MFV: r344447
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / AST / Linkage.h
1 //===----- 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"
22 #include "llvm/ADT/Optional.h"
23
24 namespace clang {
25 /// 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.
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;
38
39   explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
40       : ExplicitKind(EK), IgnoreExplicitVisibility(false),
41         IgnoreAllVisibility(false) {}
42
43   NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
44     return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
45   }
46
47   bool isTypeVisibility() const {
48     return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
49   }
50   bool isValueVisibility() const {
51     return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
52   }
53
54   /// Do an LV computation when we only care about the linkage.
55   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   }
69 };
70
71 class LinkageComputer {
72   // 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>;
80   //
81   // The unsigned represents an LVComputationKind.
82   using QueryType = std::pair<const NamedDecl *, unsigned>;
83   llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
84
85   static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
86     return std::make_pair(ND, Kind.toBits());
87   }
88
89   llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
90                                      LVComputationKind Kind) const {
91     auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
92     if (Iter == CachedLinkageInfo.end())
93       return None;
94     return Iter->second;
95   }
96
97   void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
98     CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
99   }
100
101   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,
120                                          LVComputationKind computation,
121                                          bool IgnoreVarTypeLinkage);
122
123   LinkageInfo getLVForClassMember(const NamedDecl *D,
124                                   LVComputationKind computation,
125                                   bool IgnoreVarTypeLinkage);
126
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
138 public:
139   LinkageInfo computeLVForDecl(const NamedDecl *D,
140                                LVComputationKind computation,
141                                bool IgnoreVarTypeLinkage = false);
142
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