Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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