Coverage Report

Created: 2020-09-22 08:39

/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
79.4M
        IgnoreAllVisibility(false) {}
45
46
3.07M
  NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
47
3.07M
    return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
48
3.07M
  }
49
50
50.4k
  bool isTypeVisibility() const {
51
50.4k
    return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
52
50.4k
  }
53
895k
  bool isValueVisibility() const {
54
895k
    return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
55
895k
  }
56
57
  /// Do an LV computation when we only care about the linkage.
58
77.7M
  static LVComputationKind forLinkageOnly() {
59
77.7M
    LVComputationKind Result(NamedDecl::VisibilityForValue);
60
77.7M
    Result.IgnoreExplicitVisibility = true;
61
77.7M
    Result.IgnoreAllVisibility = true;
62
77.7M
    return Result;
63
77.7M
  }
64
65
41.2M
  unsigned toBits() {
66
41.2M
    unsigned Bits = 0;
67
41.2M
    Bits = (Bits << 1) | ExplicitKind;
68
41.2M
    Bits = (Bits << 1) | IgnoreExplicitVisibility;
69
41.2M
    Bits = (Bits << 1) | IgnoreAllVisibility;
70
41.2M
    return Bits;
71
41.2M
  }
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
41.2M
  static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
91
41.2M
    return QueryType(ND, Kind.toBits());
92
41.2M
  }
93
94
  llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
95
20.6M
                                     LVComputationKind Kind) const {
96
20.6M
    auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
97
20.6M
    if (Iter == CachedLinkageInfo.end())
98
20.5M
      return None;
99
174k
    return Iter->second;
100
174k
  }
101
102
20.5M
  void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
103
20.5M
    CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
104
20.5M
  }
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
490k
  LinkageInfo computeTypeLinkageInfo(QualType T) {
152
490k
    return computeTypeLinkageInfo(T.getTypePtr());
153
490k
  }
154
155
  LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
156
157
  LinkageInfo getTypeLinkageAndVisibility(const Type *T);
158
439
  LinkageInfo getTypeLinkageAndVisibility(QualType T) {
159
439
    return getTypeLinkageAndVisibility(T.getTypePtr());
160
439
  }
161
};
162
} // namespace clang
163
164
#endif