Coverage Report

Created: 2020-02-18 08:44

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