Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/DeclOpenMP.h
Line
Count
Source (jump to first uncovered line)
1
//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- 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
/// \file
10
/// This file defines OpenMP nodes for declarative directives.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_AST_DECLOPENMP_H
15
#define LLVM_CLANG_AST_DECLOPENMP_H
16
17
#include "clang/AST/ASTContext.h"
18
#include "clang/AST/Decl.h"
19
#include "clang/AST/Expr.h"
20
#include "clang/AST/ExternalASTSource.h"
21
#include "clang/AST/OpenMPClause.h"
22
#include "clang/AST/Type.h"
23
#include "llvm/ADT/ArrayRef.h"
24
#include "llvm/Support/TrailingObjects.h"
25
26
namespace clang {
27
28
/// This is a basic class for representing single OpenMP declarative directive.
29
///
30
template <typename U> class OMPDeclarativeDirective : public U {
31
  friend class ASTDeclReader;
32
  friend class ASTDeclWriter;
33
34
  /// Get the clauses storage.
35
  MutableArrayRef<OMPClause *> getClauses() {
36
    if (!Data)
37
      return std::nullopt;
38
    return Data->getClauses();
39
  }
40
41
protected:
42
  /// Data, associated with the directive.
43
  OMPChildren *Data = nullptr;
44
45
  /// Build instance of directive.
46
  template <typename... Params>
47
6.26k
  OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
clang::OMPDeclarativeDirective<clang::Decl>::OMPDeclarativeDirective<clang::Decl::Kind, clang::DeclContext*&, clang::SourceLocation&>(clang::Decl::Kind&&, clang::DeclContext*&, clang::SourceLocation&)
Line
Count
Source
47
5.78k
  OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
clang::OMPDeclarativeDirective<clang::ValueDecl>::OMPDeclarativeDirective<clang::Decl::Kind, clang::DeclContext*&, clang::SourceLocation&, clang::DeclarationName&, clang::QualType&>(clang::Decl::Kind&&, clang::DeclContext*&, clang::SourceLocation&, clang::DeclarationName&, clang::QualType&)
Line
Count
Source
47
477
  OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
48
49
  template <typename T, typename... Params>
50
  static T *createDirective(const ASTContext &C, DeclContext *DC,
51
                            ArrayRef<OMPClause *> Clauses, unsigned NumChildren,
52
5.65k
                            Params &&... P) {
53
5.65k
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54
5.65k
        T(DC, std::forward<Params>(P)...);
55
5.65k
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56
5.65k
                                     /*AssociatedStmt=*/nullptr, NumChildren);
57
5.65k
    Inst->Data->setClauses(Clauses);
58
5.65k
    return Inst;
59
5.65k
  }
clang::OMPThreadPrivateDecl* clang::OMPDeclarativeDirective<clang::Decl>::createDirective<clang::OMPThreadPrivateDecl, clang::SourceLocation&>(clang::ASTContext const&, clang::DeclContext*, llvm::ArrayRef<clang::OMPClause*>, unsigned int, clang::SourceLocation&)
Line
Count
Source
52
4.29k
                            Params &&... P) {
53
4.29k
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54
4.29k
        T(DC, std::forward<Params>(P)...);
55
4.29k
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56
4.29k
                                     /*AssociatedStmt=*/nullptr, NumChildren);
57
4.29k
    Inst->Data->setClauses(Clauses);
58
4.29k
    return Inst;
59
4.29k
  }
clang::OMPAllocateDecl* clang::OMPDeclarativeDirective<clang::Decl>::createDirective<clang::OMPAllocateDecl, clang::SourceLocation&>(clang::ASTContext const&, clang::DeclContext*, llvm::ArrayRef<clang::OMPClause*>, unsigned int, clang::SourceLocation&)
Line
Count
Source
52
747
                            Params &&... P) {
53
747
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54
747
        T(DC, std::forward<Params>(P)...);
55
747
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56
747
                                     /*AssociatedStmt=*/nullptr, NumChildren);
57
747
    Inst->Data->setClauses(Clauses);
58
747
    return Inst;
59
747
  }
clang::OMPRequiresDecl* clang::OMPDeclarativeDirective<clang::Decl>::createDirective<clang::OMPRequiresDecl, clang::SourceLocation&>(clang::ASTContext const&, clang::DeclContext*, llvm::ArrayRef<clang::OMPClause*>, unsigned int, clang::SourceLocation&)
Line
Count
Source
52
238
                            Params &&... P) {
53
238
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54
238
        T(DC, std::forward<Params>(P)...);
55
238
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56
238
                                     /*AssociatedStmt=*/nullptr, NumChildren);
57
238
    Inst->Data->setClauses(Clauses);
58
238
    return Inst;
59
238
  }
clang::OMPDeclareMapperDecl* clang::OMPDeclarativeDirective<clang::ValueDecl>::createDirective<clang::OMPDeclareMapperDecl, clang::SourceLocation&, clang::DeclarationName&, clang::QualType&, clang::DeclarationName&, clang::OMPDeclareMapperDecl*&>(clang::ASTContext const&, clang::DeclContext*, llvm::ArrayRef<clang::OMPClause*>, unsigned int, clang::SourceLocation&, clang::DeclarationName&, clang::QualType&, clang::DeclarationName&, clang::OMPDeclareMapperDecl*&)
Line
Count
Source
52
377
                            Params &&... P) {
53
377
    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54
377
        T(DC, std::forward<Params>(P)...);
55
377
    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56
377
                                     /*AssociatedStmt=*/nullptr, NumChildren);
57
377
    Inst->Data->setClauses(Clauses);
58
377
    return Inst;
59
377
  }
60
61
  template <typename T, typename... Params>
62
  static T *createEmptyDirective(const ASTContext &C, unsigned ID,
63
                                 unsigned NumClauses, unsigned NumChildren,
64
601
                                 Params &&... P) {
65
601
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66
601
        T(nullptr, std::forward<Params>(P)...);
67
601
    Inst->Data = OMPChildren::CreateEmpty(
68
601
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69
601
    return Inst;
70
601
  }
clang::OMPThreadPrivateDecl* clang::OMPDeclarativeDirective<clang::Decl>::createEmptyDirective<clang::OMPThreadPrivateDecl>(clang::ASTContext const&, unsigned int, unsigned int, unsigned int)
Line
Count
Source
64
296
                                 Params &&... P) {
65
296
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66
296
        T(nullptr, std::forward<Params>(P)...);
67
296
    Inst->Data = OMPChildren::CreateEmpty(
68
296
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69
296
    return Inst;
70
296
  }
clang::OMPAllocateDecl* clang::OMPDeclarativeDirective<clang::Decl>::createEmptyDirective<clang::OMPAllocateDecl, clang::SourceLocation>(clang::ASTContext const&, unsigned int, unsigned int, unsigned int, clang::SourceLocation&&)
Line
Count
Source
64
173
                                 Params &&... P) {
65
173
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66
173
        T(nullptr, std::forward<Params>(P)...);
67
173
    Inst->Data = OMPChildren::CreateEmpty(
68
173
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69
173
    return Inst;
70
173
  }
clang::OMPRequiresDecl* clang::OMPDeclarativeDirective<clang::Decl>::createEmptyDirective<clang::OMPRequiresDecl, clang::SourceLocation>(clang::ASTContext const&, unsigned int, unsigned int, unsigned int, clang::SourceLocation&&)
Line
Count
Source
64
32
                                 Params &&... P) {
65
32
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66
32
        T(nullptr, std::forward<Params>(P)...);
67
32
    Inst->Data = OMPChildren::CreateEmpty(
68
32
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69
32
    return Inst;
70
32
  }
clang::OMPDeclareMapperDecl* clang::OMPDeclarativeDirective<clang::ValueDecl>::createEmptyDirective<clang::OMPDeclareMapperDecl, clang::SourceLocation, clang::DeclarationName, clang::QualType, clang::DeclarationName, std::nullptr_t>(clang::ASTContext const&, unsigned int, unsigned int, unsigned int, clang::SourceLocation&&, clang::DeclarationName&&, clang::QualType&&, clang::DeclarationName&&, std::nullptr_t&&)
Line
Count
Source
64
100
                                 Params &&... P) {
65
100
    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66
100
        T(nullptr, std::forward<Params>(P)...);
67
100
    Inst->Data = OMPChildren::CreateEmpty(
68
100
        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69
100
    return Inst;
70
100
  }
71
72
6.26k
  static size_t size(unsigned NumClauses, unsigned NumChildren) {
73
6.26k
    return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
74
6.26k
                             NumChildren);
75
6.26k
  }
clang::OMPDeclarativeDirective<clang::Decl>::size(unsigned int, unsigned int)
Line
Count
Source
72
5.78k
  static size_t size(unsigned NumClauses, unsigned NumChildren) {
73
5.78k
    return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
74
5.78k
                             NumChildren);
75
5.78k
  }
clang::OMPDeclarativeDirective<clang::ValueDecl>::size(unsigned int, unsigned int)
Line
Count
Source
72
477
  static size_t size(unsigned NumClauses, unsigned NumChildren) {
73
477
    return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
74
477
                             NumChildren);
75
477
  }
76
77
public:
78
  /// Get number of clauses.
79
  unsigned getNumClauses() const {
80
    if (!Data)
81
      return 0;
82
    return Data->getNumClauses();
83
  }
84
85
  /// Returns specified clause.
86
  ///
87
  /// \param I Number of clause.
88
  ///
89
  OMPClause *getClause(unsigned I) const { return clauses()[I]; }
90
91
38
  ArrayRef<OMPClause *> clauses() const {
92
38
    if (!Data)
93
0
      return std::nullopt;
94
38
    return Data->getClauses();
95
38
  }
96
};
97
98
/// This represents '#pragma omp threadprivate ...' directive.
99
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
100
///
101
/// \code
102
/// int a;
103
/// #pragma omp threadprivate(a)
104
/// struct A {
105
///   static int b;
106
/// #pragma omp threadprivate(b)
107
/// };
108
/// \endcode
109
///
110
class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
111
  friend class OMPDeclarativeDirective<Decl>;
112
113
  virtual void anchor();
114
115
  OMPThreadPrivateDecl(DeclContext *DC = nullptr,
116
                       SourceLocation L = SourceLocation())
117
4.59k
      : OMPDeclarativeDirective<Decl>(OMPThreadPrivate, DC, L) {}
118
119
176
  ArrayRef<const Expr *> getVars() const {
120
176
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
121
176
    return llvm::ArrayRef(Storage, Data->getNumChildren());
122
176
  }
123
124
6.82k
  MutableArrayRef<Expr *> getVars() {
125
6.82k
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
126
6.82k
    return llvm::MutableArrayRef(Storage, Data->getNumChildren());
127
6.82k
  }
128
129
  void setVars(ArrayRef<Expr *> VL);
130
131
public:
132
  static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
133
                                      SourceLocation L,
134
                                      ArrayRef<Expr *> VL);
135
  static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
136
                                                  unsigned ID, unsigned N);
137
138
  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
139
  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
140
  typedef llvm::iterator_range<varlist_iterator> varlist_range;
141
  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
142
143
0
  unsigned varlist_size() const { return Data->getNumChildren(); }
144
632
  bool varlist_empty() const { return Data->getChildren().empty(); }
145
146
312
  varlist_range varlists() {
147
312
    return varlist_range(varlist_begin(), varlist_end());
148
312
  }
149
88
  varlist_const_range varlists() const {
150
88
    return varlist_const_range(varlist_begin(), varlist_end());
151
88
  }
152
1.58k
  varlist_iterator varlist_begin() { return getVars().begin(); }
153
944
  varlist_iterator varlist_end() { return getVars().end(); }
154
88
  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
155
88
  varlist_const_iterator varlist_end() const { return getVars().end(); }
156
157
3.53M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
158
3.53M
  static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
159
};
160
161
enum class OMPDeclareReductionInitKind {
162
  Call,   // Initialized by function call.
163
  Direct, // omp_priv(<expr>)
164
  Copy    // omp_priv = <expr>
165
};
166
167
/// This represents '#pragma omp declare reduction ...' directive.
168
/// For example, in the following, declared reduction 'foo' for types 'int' and
169
/// 'float':
170
///
171
/// \code
172
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in)
173
///                     initializer (omp_priv = 0)
174
/// \endcode
175
///
176
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
177
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
178
  // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
179
  // to save some space. Use the provided accessors to access it.
180
181
  friend class ASTDeclReader;
182
  /// Combiner for declare reduction construct.
183
  Expr *Combiner = nullptr;
184
  /// Initializer for declare reduction construct.
185
  Expr *Initializer = nullptr;
186
  /// In parameter of the combiner.
187
  Expr *In = nullptr;
188
  /// Out parameter of the combiner.
189
  Expr *Out = nullptr;
190
  /// Priv parameter of the initializer.
191
  Expr *Priv = nullptr;
192
  /// Orig parameter of the initializer.
193
  Expr *Orig = nullptr;
194
195
  /// Reference to the previous declare reduction construct in the same
196
  /// scope with the same name. Required for proper templates instantiation if
197
  /// the declare reduction construct is declared inside compound statement.
198
  LazyDeclPtr PrevDeclInScope;
199
200
  void anchor() override;
201
202
  OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
203
                          DeclarationName Name, QualType Ty,
204
                          OMPDeclareReductionDecl *PrevDeclInScope);
205
206
0
  void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
207
0
    PrevDeclInScope = Prev;
208
0
  }
209
210
public:
211
  /// Create declare reduction node.
212
  static OMPDeclareReductionDecl *
213
  Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
214
         QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
215
  /// Create deserialized declare reduction node.
216
  static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
217
                                                     unsigned ID);
218
219
  /// Get combiner expression of the declare reduction construct.
220
382
  Expr *getCombiner() { return Combiner; }
221
159
  const Expr *getCombiner() const { return Combiner; }
222
  /// Get In variable of the combiner.
223
434
  Expr *getCombinerIn() { return In; }
224
147
  const Expr *getCombinerIn() const { return In; }
225
  /// Get Out variable of the combiner.
226
434
  Expr *getCombinerOut() { return Out; }
227
147
  const Expr *getCombinerOut() const { return Out; }
228
  /// Set combiner expression for the declare reduction construct.
229
942
  void setCombiner(Expr *E) { Combiner = E; }
230
  /// Set combiner In and Out vars.
231
996
  void setCombinerData(Expr *InE, Expr *OutE) {
232
996
    In = InE;
233
996
    Out = OutE;
234
996
  }
235
236
  /// Get initializer expression (if specified) of the declare reduction
237
  /// construct.
238
794
  Expr *getInitializer() { return Initializer; }
239
340
  const Expr *getInitializer() const { return Initializer; }
240
  /// Get initializer kind.
241
491
  OMPDeclareReductionInitKind getInitializerKind() const {
242
491
    return static_cast<OMPDeclareReductionInitKind>(
243
491
        OMPDeclareReductionDeclBits.InitializerKind);
244
491
  }
245
  /// Get Orig variable of the initializer.
246
250
  Expr *getInitOrig() { return Orig; }
247
79
  const Expr *getInitOrig() const { return Orig; }
248
  /// Get Priv variable of the initializer.
249
298
  Expr *getInitPriv() { return Priv; }
250
79
  const Expr *getInitPriv() const { return Priv; }
251
  /// Set initializer expression for the declare reduction construct.
252
1.37k
  void setInitializer(Expr *E, OMPDeclareReductionInitKind IK) {
253
1.37k
    Initializer = E;
254
1.37k
    OMPDeclareReductionDeclBits.InitializerKind = llvm::to_underlying(IK);
255
1.37k
  }
256
  /// Set initializer Orig and Priv vars.
257
436
  void setInitializerData(Expr *OrigE, Expr *PrivE) {
258
436
    Orig = OrigE;
259
436
    Priv = PrivE;
260
436
  }
261
262
  /// Get reference to previous declare reduction construct in the same
263
  /// scope with the same name.
264
  OMPDeclareReductionDecl *getPrevDeclInScope();
265
  const OMPDeclareReductionDecl *getPrevDeclInScope() const;
266
267
3.65M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
268
209M
  static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
269
0
  static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
270
0
    return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
271
0
  }
272
0
  static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
273
0
    return static_cast<OMPDeclareReductionDecl *>(
274
0
        const_cast<DeclContext *>(DC));
275
0
  }
276
};
277
278
/// This represents '#pragma omp declare mapper ...' directive. Map clauses are
279
/// allowed to use with this directive. The following example declares a user
280
/// defined mapper for the type 'struct vec'. This example instructs the fields
281
/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.
282
///
283
/// \code
284
/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
285
/// \endcode
286
class OMPDeclareMapperDecl final : public OMPDeclarativeDirective<ValueDecl>,
287
                                   public DeclContext {
288
  friend class OMPDeclarativeDirective<ValueDecl>;
289
  friend class ASTDeclReader;
290
  friend class ASTDeclWriter;
291
292
  /// Mapper variable, which is 'v' in the example above
293
  Expr *MapperVarRef = nullptr;
294
295
  /// Name of the mapper variable
296
  DeclarationName VarName;
297
298
  LazyDeclPtr PrevDeclInScope;
299
300
  void anchor() override;
301
302
  OMPDeclareMapperDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
303
                       QualType Ty, DeclarationName VarName,
304
                       OMPDeclareMapperDecl *PrevDeclInScope)
305
477
      : OMPDeclarativeDirective<ValueDecl>(OMPDeclareMapper, DC, L, Name, Ty),
306
477
        DeclContext(OMPDeclareMapper), VarName(VarName),
307
477
        PrevDeclInScope(PrevDeclInScope) {}
308
309
0
  void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
310
0
    PrevDeclInScope = Prev;
311
0
  }
312
313
public:
314
  /// Creates declare mapper node.
315
  static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
316
                                      SourceLocation L, DeclarationName Name,
317
                                      QualType T, DeclarationName VarName,
318
                                      ArrayRef<OMPClause *> Clauses,
319
                                      OMPDeclareMapperDecl *PrevDeclInScope);
320
  /// Creates deserialized declare mapper node.
321
  static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,
322
                                                  unsigned N);
323
324
  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
325
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
326
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
327
  using clauselist_const_range =
328
      llvm::iterator_range<clauselist_const_iterator>;
329
330
0
  unsigned clauselist_size() const { return Data->getNumClauses(); }
331
144
  bool clauselist_empty() const { return Data->getClauses().empty(); }
332
333
172
  clauselist_range clauselists() {
334
172
    return clauselist_range(clauselist_begin(), clauselist_end());
335
172
  }
336
0
  clauselist_const_range clauselists() const {
337
0
    return clauselist_const_range(clauselist_begin(), clauselist_end());
338
0
  }
339
200
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
340
172
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
341
0
  clauselist_const_iterator clauselist_begin() const {
342
0
    return Data->getClauses().begin();
343
0
  }
344
0
  clauselist_const_iterator clauselist_end() const {
345
0
    return Data->getClauses().end();
346
0
  }
347
348
  /// Get the variable declared in the mapper
349
28
  Expr *getMapperVarRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
350
38
  const Expr *getMapperVarRef() const {
351
38
    return cast_or_null<Expr>(Data->getChildren()[0]);
352
38
  }
353
  /// Set the variable declared in the mapper
354
377
  void setMapperVarRef(Expr *MapperVarRefE) {
355
377
    Data->getChildren()[0] = MapperVarRefE;
356
377
  }
357
358
  /// Get the name of the variable declared in the mapper
359
272
  DeclarationName getVarName() { return VarName; }
360
361
  /// Get reference to previous declare mapper construct in the same
362
  /// scope with the same name.
363
  OMPDeclareMapperDecl *getPrevDeclInScope();
364
  const OMPDeclareMapperDecl *getPrevDeclInScope() const;
365
366
3.64M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
367
33.3M
  static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
368
0
  static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
369
0
    return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
370
0
  }
371
0
  static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {
372
0
    return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));
373
0
  }
374
};
375
376
/// Pseudo declaration for capturing expressions. Also is used for capturing of
377
/// non-static data members in non-static member functions.
378
///
379
/// Clang supports capturing of variables only, but OpenMP 4.5 allows to
380
/// privatize non-static members of current class in non-static member
381
/// functions. This pseudo-declaration allows properly handle this kind of
382
/// capture by wrapping captured expression into a variable-like declaration.
383
class OMPCapturedExprDecl final : public VarDecl {
384
  friend class ASTDeclReader;
385
  void anchor() override;
386
387
  OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
388
                      QualType Type, TypeSourceInfo *TInfo,
389
                      SourceLocation StartLoc)
390
88.6k
      : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
391
88.6k
                SC_None) {
392
88.6k
    setImplicit();
393
88.6k
  }
394
395
public:
396
  static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
397
                                     IdentifierInfo *Id, QualType T,
398
                                     SourceLocation StartLoc);
399
400
  static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
401
402
  SourceRange getSourceRange() const override LLVM_READONLY;
403
404
  // Implement isa/cast/dyncast/etc.
405
74.2M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
406
74.2M
  static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
407
};
408
409
/// This represents '#pragma omp requires...' directive.
410
/// For example
411
///
412
/// \code
413
/// #pragma omp requires unified_address
414
/// \endcode
415
///
416
class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
417
  friend class OMPDeclarativeDirective<Decl>;
418
  friend class ASTDeclReader;
419
420
  virtual void anchor();
421
422
  OMPRequiresDecl(DeclContext *DC, SourceLocation L)
423
270
      : OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}
424
425
public:
426
  /// Create requires node.
427
  static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
428
                                 SourceLocation L, ArrayRef<OMPClause *> CL);
429
  /// Create deserialized requires node.
430
  static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
431
                                             unsigned N);
432
433
  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
434
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
435
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
436
  using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
437
438
0
  unsigned clauselist_size() const { return Data->getNumClauses(); }
439
48
  bool clauselist_empty() const { return Data->getClauses().empty(); }
440
441
0
  clauselist_range clauselists() {
442
0
    return clauselist_range(clauselist_begin(), clauselist_end());
443
0
  }
444
36.6k
  clauselist_const_range clauselists() const {
445
36.6k
    return clauselist_const_range(clauselist_begin(), clauselist_end());
446
36.6k
  }
447
48
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
448
48
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
449
36.6k
  clauselist_const_iterator clauselist_begin() const {
450
36.6k
    return Data->getClauses().begin();
451
36.6k
  }
452
36.6k
  clauselist_const_iterator clauselist_end() const {
453
36.6k
    return Data->getClauses().end();
454
36.6k
  }
455
456
3.53M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
457
3.53M
  static bool classofKind(Kind K) { return K == OMPRequires; }
458
};
459
460
/// This represents '#pragma omp allocate ...' directive.
461
/// For example, in the following, the default allocator is used for both 'a'
462
/// and 'A::b':
463
///
464
/// \code
465
/// int a;
466
/// #pragma omp allocate(a)
467
/// struct A {
468
///   static int b;
469
/// #pragma omp allocate(b)
470
/// };
471
/// \endcode
472
///
473
class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
474
  friend class OMPDeclarativeDirective<Decl>;
475
  friend class ASTDeclReader;
476
477
  virtual void anchor();
478
479
  OMPAllocateDecl(DeclContext *DC, SourceLocation L)
480
920
      : OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}
481
482
200
  ArrayRef<const Expr *> getVars() const {
483
200
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
484
200
    return llvm::ArrayRef(Storage, Data->getNumChildren());
485
200
  }
486
487
1.47k
  MutableArrayRef<Expr *> getVars() {
488
1.47k
    auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
489
1.47k
    return llvm::MutableArrayRef(Storage, Data->getNumChildren());
490
1.47k
  }
491
492
  void setVars(ArrayRef<Expr *> VL);
493
494
public:
495
  static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
496
                                 SourceLocation L, ArrayRef<Expr *> VL,
497
                                 ArrayRef<OMPClause *> CL);
498
  static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
499
                                             unsigned NVars, unsigned NClauses);
500
501
  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
502
  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
503
  typedef llvm::iterator_range<varlist_iterator> varlist_range;
504
  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
505
  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
506
  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
507
  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
508
  using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
509
510
0
  unsigned varlist_size() const { return Data->getNumChildren(); }
511
182
  bool varlist_empty() const { return Data->getChildren().empty(); }
512
0
  unsigned clauselist_size() const { return Data->getNumClauses(); }
513
182
  bool clauselist_empty() const { return Data->getClauses().empty(); }
514
515
82
  varlist_range varlists() {
516
82
    return varlist_range(varlist_begin(), varlist_end());
517
82
  }
518
100
  varlist_const_range varlists() const {
519
100
    return varlist_const_range(varlist_begin(), varlist_end());
520
100
  }
521
462
  varlist_iterator varlist_begin() { return getVars().begin(); }
522
264
  varlist_iterator varlist_end() { return getVars().end(); }
523
100
  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
524
100
  varlist_const_iterator varlist_end() const { return getVars().end(); }
525
526
176
  clauselist_range clauselists() {
527
176
    return clauselist_range(clauselist_begin(), clauselist_end());
528
176
  }
529
8
  clauselist_const_range clauselists() const {
530
8
    return clauselist_const_range(clauselist_begin(), clauselist_end());
531
8
  }
532
176
  clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
533
176
  clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
534
8
  clauselist_const_iterator clauselist_begin() const {
535
8
    return Data->getClauses().begin();
536
8
  }
537
8
  clauselist_const_iterator clauselist_end() const {
538
8
    return Data->getClauses().end();
539
8
  }
540
541
3.53M
  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
542
3.53M
  static bool classofKind(Kind K) { return K == OMPAllocate; }
543
};
544
545
} // end namespace clang
546
547
#endif