Coverage Report

Created: 2021-01-19 06:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/GlobalDecl.h
Line
Count
Source (jump to first uncovered line)
1
//===- GlobalDecl.h - Global declaration holder -----------------*- 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
// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
10
// together with its type.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_AST_GLOBALDECL_H
15
#define LLVM_CLANG_AST_GLOBALDECL_H
16
17
#include "clang/AST/Attr.h"
18
#include "clang/AST/DeclCXX.h"
19
#include "clang/AST/DeclObjC.h"
20
#include "clang/AST/DeclOpenMP.h"
21
#include "clang/Basic/ABI.h"
22
#include "clang/Basic/LLVM.h"
23
#include "llvm/ADT/DenseMapInfo.h"
24
#include "llvm/ADT/PointerIntPair.h"
25
#include "llvm/Support/Casting.h"
26
#include "llvm/Support/type_traits.h"
27
#include <cassert>
28
29
namespace clang {
30
31
enum class DynamicInitKind : unsigned {
32
  NoStub = 0,
33
  Initializer,
34
  AtExit,
35
  GlobalArrayDestructor
36
};
37
38
enum class KernelReferenceKind : unsigned {
39
  Kernel = 0,
40
  Stub = 1,
41
};
42
43
/// GlobalDecl - represents a global declaration. This can either be a
44
/// CXXConstructorDecl and the constructor type (Base, Complete).
45
/// a CXXDestructorDecl and the destructor type (Base, Complete),
46
/// a FunctionDecl and the kernel reference type (Kernel, Stub), or
47
/// a VarDecl, a FunctionDecl or a BlockDecl.
48
///
49
/// When a new type of GlobalDecl is added, the following places should
50
/// be updated to convert a Decl* to a GlobalDecl:
51
/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp.
52
/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp
53
/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp
54
///
55
class GlobalDecl {
56
  llvm::PointerIntPair<const Decl *, 3> Value;
57
  unsigned MultiVersionIndex = 0;
58
59
17.7M
  void Init(const Decl *D) {
60
17.7M
    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
61
17.7M
    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
62
17.7M
    assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!");
63
64
17.7M
    Value.setPointer(D);
65
17.7M
  }
66
67
public:
68
33.0M
  GlobalDecl() = default;
69
2.06M
  GlobalDecl(const VarDecl *D) { Init(D);}
70
  GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
71
11.1M
      : MultiVersionIndex(MVIndex) {
72
11.1M
    if (!D->hasAttr<CUDAGlobalAttr>()) {
73
11.1M
      Init(D);
74
11.1M
      return;
75
11.1M
    }
76
176
    Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D)));
77
176
  }
78
  GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind)
79
87
      : Value(D, unsigned(Kind)) {
80
87
    assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!");
81
87
  }
82
4.51M
  GlobalDecl(const NamedDecl *D) { Init(D); }
83
4.23k
  GlobalDecl(const BlockDecl *D) { Init(D); }
84
72.6k
  GlobalDecl(const CapturedDecl *D) { Init(D); }
85
26.4k
  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
86
10
  GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
87
0
  GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); }
88
444k
  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
89
115k
  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
90
  GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
91
6.30k
      : Value(D, unsigned(StubKind)) {}
92
93
4.03M
  GlobalDecl getCanonicalDecl() const {
94
4.03M
    GlobalDecl CanonGD;
95
4.03M
    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
96
4.03M
    CanonGD.Value.setInt(Value.getInt());
97
4.03M
    CanonGD.MultiVersionIndex = MultiVersionIndex;
98
99
4.03M
    return CanonGD;
100
4.03M
  }
101
102
60.8M
  const Decl *getDecl() const { return Value.getPointer(); }
103
104
383k
  CXXCtorType getCtorType() const {
105
383k
    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
106
383k
    return static_cast<CXXCtorType>(Value.getInt());
107
383k
  }
108
109
276k
  CXXDtorType getDtorType() const {
110
276k
    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
111
276k
    return static_cast<CXXDtorType>(Value.getInt());
112
276k
  }
113
114
1.51k
  DynamicInitKind getDynamicInitKind() const {
115
1.51k
    assert(isa<VarDecl>(getDecl()) &&
116
1.51k
           cast<VarDecl>(getDecl())->hasGlobalStorage() &&
117
1.51k
           "Decl is not a global variable!");
118
1.51k
    return static_cast<DynamicInitKind>(Value.getInt());
119
1.51k
  }
120
121
84
  unsigned getMultiVersionIndex() const {
122
84
    assert(isa<FunctionDecl>(
123
84
               getDecl()) &&
124
84
               !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
125
84
           !isa<CXXConstructorDecl>(getDecl()) &&
126
84
           !isa<CXXDestructorDecl>(getDecl()) &&
127
84
           "Decl is not a plain FunctionDecl!");
128
84
    return MultiVersionIndex;
129
84
  }
130
131
267
  KernelReferenceKind getKernelReferenceKind() const {
132
267
    assert(isa<FunctionDecl>(getDecl()) &&
133
267
           cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
134
267
           "Decl is not a GPU kernel!");
135
267
    return static_cast<KernelReferenceKind>(Value.getInt());
136
267
  }
137
138
90.0M
  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
139
90.0M
    return LHS.Value == RHS.Value &&
140
18.9M
           LHS.MultiVersionIndex == RHS.MultiVersionIndex;
141
90.0M
  }
142
143
14.6M
  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
144
145
4.31M
  explicit operator bool() const { return getAsOpaquePtr(); }
146
147
10.3M
  static GlobalDecl getFromOpaquePtr(void *P) {
148
10.3M
    GlobalDecl GD;
149
10.3M
    GD.Value.setFromOpaqueValue(P);
150
10.3M
    return GD;
151
10.3M
  }
152
153
176
  static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
154
94
    return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel
155
82
                                         : KernelReferenceKind::Stub;
156
176
  }
157
158
4.38M
  GlobalDecl getWithDecl(const Decl *D) {
159
4.38M
    GlobalDecl Result(*this);
160
4.38M
    Result.Value.setPointer(D);
161
4.38M
    return Result;
162
4.38M
  }
163
164
17.2k
  GlobalDecl getWithCtorType(CXXCtorType Type) {
165
17.2k
    assert(isa<CXXConstructorDecl>(getDecl()));
166
17.2k
    GlobalDecl Result(*this);
167
17.2k
    Result.Value.setInt(Type);
168
17.2k
    return Result;
169
17.2k
  }
170
171
7.53k
  GlobalDecl getWithDtorType(CXXDtorType Type) {
172
7.53k
    assert(isa<CXXDestructorDecl>(getDecl()));
173
7.53k
    GlobalDecl Result(*this);
174
7.53k
    Result.Value.setInt(Type);
175
7.53k
    return Result;
176
7.53k
  }
177
178
70
  GlobalDecl getWithMultiVersionIndex(unsigned Index) {
179
70
    assert(isa<FunctionDecl>(getDecl()) &&
180
70
           !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
181
70
           !isa<CXXConstructorDecl>(getDecl()) &&
182
70
           !isa<CXXDestructorDecl>(getDecl()) &&
183
70
           "Decl is not a plain FunctionDecl!");
184
70
    GlobalDecl Result(*this);
185
70
    Result.MultiVersionIndex = Index;
186
70
    return Result;
187
70
  }
188
189
49
  GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) {
190
49
    assert(isa<FunctionDecl>(getDecl()) &&
191
49
           cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
192
49
           "Decl is not a GPU kernel!");
193
49
    GlobalDecl Result(*this);
194
49
    Result.Value.setInt(unsigned(Kind));
195
49
    return Result;
196
49
  }
197
};
198
199
} // namespace clang
200
201
namespace llvm {
202
203
  template<> struct DenseMapInfo<clang::GlobalDecl> {
204
13.1M
    static inline clang::GlobalDecl getEmptyKey() {
205
13.1M
      return clang::GlobalDecl();
206
13.1M
    }
207
208
10.3M
    static inline clang::GlobalDecl getTombstoneKey() {
209
10.3M
      return clang::GlobalDecl::
210
10.3M
        getFromOpaquePtr(reinterpret_cast<void*>(-1));
211
10.3M
    }
212
213
10.3M
    static unsigned getHashValue(clang::GlobalDecl GD) {
214
10.3M
      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
215
10.3M
    }
216
217
    static bool isEqual(clang::GlobalDecl LHS,
218
90.0M
                        clang::GlobalDecl RHS) {
219
90.0M
      return LHS == RHS;
220
90.0M
    }
221
  };
222
223
} // namespace llvm
224
225
#endif // LLVM_CLANG_AST_GLOBALDECL_H