Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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/Decl.h"
18
#include "clang/AST/DeclCXX.h"
19
#include "clang/AST/Type.h"
20
#include "llvm/ADT/DenseMap.h"
21
#include "llvm/ADT/Optional.h"
22
#include "llvm/ADT/PointerIntPair.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
  enum { NumLVComputationKindBits = 3 };
40
41
  explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
42
      : ExplicitKind(EK), IgnoreExplicitVisibility(false),
43
59.5M
        IgnoreAllVisibility(false) {}
44
45
7.06M
  NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
46
7.06M
    return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
47
7.06M
  }
48
49
236k
  bool isTypeVisibility() const {
50
236k
    return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
51
236k
  }
52
2.05M
  bool isValueVisibility() const {
53
2.05M
    return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
54
2.05M
  }
55
56
  /// Do an LV computation when we only care about the linkage.
57
56.3M
  static LVComputationKind forLinkageOnly() {
58
56.3M
    LVComputationKind Result(NamedDecl::VisibilityForValue);
59
56.3M
    Result.IgnoreExplicitVisibility = true;
60
56.3M
    Result.IgnoreAllVisibility = true;
61
56.3M
    return Result;
62
56.3M
  }
63
64
24.4M
  unsigned toBits() {
65
24.4M
    unsigned Bits = 0;
66
24.4M
    Bits = (Bits << 1) | ExplicitKind;
67
24.4M
    Bits = (Bits << 1) | IgnoreExplicitVisibility;
68
24.4M
    Bits = (Bits << 1) | IgnoreAllVisibility;
69
24.4M
    return Bits;
70
24.4M
  }
71
};
72
73
class LinkageComputer {
74
  // We have a cache for repeated linkage/visibility computations. This saves us
75
  // from exponential behavior in heavily templated code, such as:
76
  //
77
  // template <typename T, typename V> struct {};
78
  // using A = int;
79
  // using B = Foo<A, A>;
80
  // using C = Foo<B, B>;
81
  // using D = Foo<C, C>;
82
  //
83
  // The integer represents an LVComputationKind.
84
  using QueryType =
85
      llvm::PointerIntPair<const NamedDecl *,
86
                           LVComputationKind::NumLVComputationKindBits>;
87
  llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
88
89
24.4M
  static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
90
24.4M
    return QueryType(ND, Kind.toBits());
91
24.4M
  }
92
93
  llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
94
12.3M
                                     LVComputationKind Kind) const {
95
12.3M
    auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
96
12.3M
    if (Iter == CachedLinkageInfo.end())
97
12.0M
      return None;
98
276k
    return Iter->second;
99
276k
  }
100
101
12.0M
  void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
102
12.0M
    CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
103
12.0M
  }
104
105
  LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
106
                                           LVComputationKind computation);
107
108
  LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
109
                                           LVComputationKind computation);
110
111
  void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
112
                       const FunctionTemplateSpecializationInfo *specInfo,
113
                       LVComputationKind computation);
114
115
  void mergeTemplateLV(LinkageInfo &LV,
116
                       const ClassTemplateSpecializationDecl *spec,
117
                       LVComputationKind computation);
118
119
  void mergeTemplateLV(LinkageInfo &LV,
120
                       const VarTemplateSpecializationDecl *spec,
121
                       LVComputationKind computation);
122
123
  LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
124
                                         LVComputationKind computation,
125
                                         bool IgnoreVarTypeLinkage);
126
127
  LinkageInfo getLVForClassMember(const NamedDecl *D,
128
                                  LVComputationKind computation,
129
                                  bool IgnoreVarTypeLinkage);
130
131
  LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
132
                              LVComputationKind computation);
133
134
  LinkageInfo getLVForLocalDecl(const NamedDecl *D,
135
                                LVComputationKind computation);
136
137
  LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
138
139
  LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
140
                                            LVComputationKind computation);
141
142
public:
143
  LinkageInfo computeLVForDecl(const NamedDecl *D,
144
                               LVComputationKind computation,
145
                               bool IgnoreVarTypeLinkage = false);
146
147
  LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
148
149
  LinkageInfo computeTypeLinkageInfo(const Type *T);
150
385k
  LinkageInfo computeTypeLinkageInfo(QualType T) {
151
385k
    return computeTypeLinkageInfo(T.getTypePtr());
152
385k
  }
153
154
  LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
155
156
  LinkageInfo getTypeLinkageAndVisibility(const Type *T);
157
246
  LinkageInfo getTypeLinkageAndVisibility(QualType T) {
158
246
    return getTypeLinkageAndVisibility(T.getTypePtr());
159
246
  }
160
};
161
} // namespace clang
162
163
#endif