blob: fde9841cdff7cfefac98829c7ddb24a5245270b1 [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,
Vitaly Buka17def212017-09-21 02:51:56 +000027 IgnoreAllVisibilityBit = 4
George Burgess IV99db3ea2017-08-09 04:02:49 +000028};
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};
58
59class LinkageComputer {
George Burgess IV35cb4f82017-08-09 04:12:17 +000060 // We have a cache for repeated linkage/visibility computations. This saves us
61 // from exponential behavior in heavily templated code, such as:
62 //
63 // template <typename T, typename V> struct {};
64 // using A = int;
65 // using B = Foo<A, A>;
66 // using C = Foo<B, B>;
67 // using D = Foo<C, C>;
George Burgess IVb8709ba2017-08-09 21:20:41 +000068 //
69 // Note that the unsigned is actually a LVComputationKind; ubsan's enum
70 // sanitizer doesn't like tombstone/empty markers outside of
71 // LVComputationKind's range.
72 using QueryType = std::pair<const NamedDecl *, unsigned>;
George Burgess IV35cb4f82017-08-09 04:12:17 +000073 llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
George Burgess IVb8709ba2017-08-09 21:20:41 +000074
75 static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
76 return std::make_pair(ND, static_cast<unsigned>(Kind));
77 }
78
George Burgess IV35cb4f82017-08-09 04:12:17 +000079 llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
80 LVComputationKind Kind) const {
George Burgess IVb8709ba2017-08-09 21:20:41 +000081 auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
George Burgess IV35cb4f82017-08-09 04:12:17 +000082 if (Iter == CachedLinkageInfo.end())
83 return None;
84 return Iter->second;
85 }
86
87 void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
George Burgess IVb8709ba2017-08-09 21:20:41 +000088 CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
George Burgess IV35cb4f82017-08-09 04:12:17 +000089 }
90
George Burgess IV99db3ea2017-08-09 04:02:49 +000091 LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
92 LVComputationKind computation);
93
94 LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
95 LVComputationKind computation);
96
97 void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
98 const FunctionTemplateSpecializationInfo *specInfo,
99 LVComputationKind computation);
100
101 void mergeTemplateLV(LinkageInfo &LV,
102 const ClassTemplateSpecializationDecl *spec,
103 LVComputationKind computation);
104
105 void mergeTemplateLV(LinkageInfo &LV,
106 const VarTemplateSpecializationDecl *spec,
107 LVComputationKind computation);
108
109 LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
110 LVComputationKind computation);
111
112 LinkageInfo getLVForClassMember(const NamedDecl *D,
113 LVComputationKind computation);
114
115 LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
116 LVComputationKind computation);
117
118 LinkageInfo getLVForLocalDecl(const NamedDecl *D,
119 LVComputationKind computation);
120
121 LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
122
123 LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
124 LVComputationKind computation);
125
126public:
127 LinkageInfo computeLVForDecl(const NamedDecl *D,
128 LVComputationKind computation);
129
130 LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
131
132 LinkageInfo computeTypeLinkageInfo(const Type *T);
133 LinkageInfo computeTypeLinkageInfo(QualType T) {
134 return computeTypeLinkageInfo(T.getTypePtr());
135 }
136
137 LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
138
139 LinkageInfo getTypeLinkageAndVisibility(const Type *T);
140 LinkageInfo getTypeLinkageAndVisibility(QualType T) {
141 return getTypeLinkageAndVisibility(T.getTypePtr());
142 }
143};
144} // namespace clang
145
146#endif