blob: 5f3458dfb600a9cf33495c1011a5314ff3c72b9f [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 {
25enum : unsigned {
26 IgnoreExplicitVisibilityBit = 2,
27 IgnoreAllVisibilityBit = 4
28};
29
30/// Kinds of LV computation. The linkage side of the computation is
31/// always the same, but different things can change how visibility is
32/// computed.
33enum LVComputationKind {
34 /// Do an LV computation for, ultimately, a type.
35 /// Visibility may be restricted by type visibility settings and
36 /// the visibility of template arguments.
37 LVForType = NamedDecl::VisibilityForType,
38
39 /// Do an LV computation for, ultimately, a non-type declaration.
40 /// Visibility may be restricted by value visibility settings and
41 /// the visibility of template arguments.
42 LVForValue = NamedDecl::VisibilityForValue,
43
44 /// Do an LV computation for, ultimately, a type that already has
45 /// some sort of explicit visibility. Visibility may only be
46 /// restricted by the visibility of template arguments.
47 LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),
48
49 /// Do an LV computation for, ultimately, a non-type declaration
50 /// that already has some sort of explicit visibility. Visibility
51 /// may only be restricted by the visibility of template arguments.
52 LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),
53
54 /// Do an LV computation when we only care about the linkage.
55 LVForLinkageOnly =
56 LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit
57};
George Burgess IV35cb4f82017-08-09 04:12:17 +000058} // namespace clang
George Burgess IV99db3ea2017-08-09 04:02:49 +000059
George Burgess IV35cb4f82017-08-09 04:12:17 +000060namespace llvm {
61template <> struct DenseMapInfo<clang::LVComputationKind> {
62 static inline clang::LVComputationKind getEmptyKey() {
63 return static_cast<clang::LVComputationKind>(-1);
64 }
65 static inline clang::LVComputationKind getTombstoneKey() {
66 return static_cast<clang::LVComputationKind>(-2);
67 }
68 static unsigned getHashValue(const clang::LVComputationKind &Val) {
69 return Val;
70 }
71 static bool isEqual(const clang::LVComputationKind &LHS,
72 const clang::LVComputationKind &RHS) {
73 return LHS == RHS;
74 }
75};
76} // namespace llvm
77
78namespace clang {
George Burgess IV99db3ea2017-08-09 04:02:49 +000079class LinkageComputer {
George Burgess IV35cb4f82017-08-09 04:12:17 +000080 // We have a cache for repeated linkage/visibility computations. This saves us
81 // from exponential behavior in heavily templated code, such as:
82 //
83 // template <typename T, typename V> struct {};
84 // using A = int;
85 // using B = Foo<A, A>;
86 // using C = Foo<B, B>;
87 // using D = Foo<C, C>;
88 using QueryType = std::pair<const NamedDecl *, LVComputationKind>;
89 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
90 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
91 LVComputationKind Kind) const {
92 auto Iter = CachedLinkageInfo.find(std::make_pair(ND, Kind));
93 if (Iter == CachedLinkageInfo.end())
94 return None;
95 return Iter->second;
96 }
97
98 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
99 CachedLinkageInfo[std::make_pair(ND, Kind)] = Info;
100 }
101
George Burgess IV99db3ea2017-08-09 04:02:49 +0000102 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
103 LVComputationKind computation);
104
105 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
106 LVComputationKind computation);
107
108 void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
109 const FunctionTemplateSpecializationInfo *specInfo,
110 LVComputationKind computation);
111
112 void mergeTemplateLV(LinkageInfo &LV,
113 const ClassTemplateSpecializationDecl *spec,
114 LVComputationKind computation);
115
116 void mergeTemplateLV(LinkageInfo &LV,
117 const VarTemplateSpecializationDecl *spec,
118 LVComputationKind computation);
119
120 LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
121 LVComputationKind computation);
122
123 LinkageInfo getLVForClassMember(const NamedDecl *D,
124 LVComputationKind computation);
125
126 LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
127 LVComputationKind computation);
128
129 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
130 LVComputationKind computation);
131
132 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
133
134 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
135 LVComputationKind computation);
136
137public:
138 LinkageInfo computeLVForDecl(const NamedDecl *D,
139 LVComputationKind computation);
140
141 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
142
143 LinkageInfo computeTypeLinkageInfo(const Type *T);
144 LinkageInfo computeTypeLinkageInfo(QualType T) {
145 return computeTypeLinkageInfo(T.getTypePtr());
146 }
147
148 LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
149
150 LinkageInfo getTypeLinkageAndVisibility(const Type *T);
151 LinkageInfo getTypeLinkageAndVisibility(QualType T) {
152 return getTypeLinkageAndVisibility(T.getTypePtr());
153 }
154};
155} // namespace clang
156
157#endif