Coverage Report

Created: 2020-09-15 12:33

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/ExprOpenMP.h
Line
Count
Source (jump to first uncovered line)
1
//===--- ExprOpenMP.h - Classes for representing expressions ----*- 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 defines the Expr interface and subclasses.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_AST_EXPROPENMP_H
14
#define LLVM_CLANG_AST_EXPROPENMP_H
15
16
#include "clang/AST/ComputeDependence.h"
17
#include "clang/AST/Expr.h"
18
19
namespace clang {
20
/// OpenMP 5.0 [2.1.5, Array Sections].
21
/// To specify an array section in an OpenMP construct, array subscript
22
/// expressions are extended with the following syntax:
23
/// \code
24
/// [ lower-bound : length : stride ]
25
/// [ lower-bound : length : ]
26
/// [ lower-bound : length ]
27
/// [ lower-bound : : stride ]
28
/// [ lower-bound : : ]
29
/// [ lower-bound : ]
30
/// [ : length : stride ]
31
/// [ : length : ]
32
/// [ : length ]
33
/// [ : : stride ]
34
/// [ : : ]
35
/// [ : ]
36
/// \endcode
37
/// The array section must be a subset of the original array.
38
/// Array sections are allowed on multidimensional arrays. Base language array
39
/// subscript expressions can be used to specify length-one dimensions of
40
/// multidimensional array sections.
41
/// Each of the lower-bound, length, and stride expressions if specified must be
42
/// an integral type expressions of the base language. When evaluated
43
/// they represent a set of integer values as follows:
44
/// \code
45
/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
46
/// lower-bound + ((length - 1) * stride) }
47
/// \endcode
48
/// The lower-bound and length must evaluate to non-negative integers.
49
/// The stride must evaluate to a positive integer.
50
/// When the size of the array dimension is not known, the length must be
51
/// specified explicitly.
52
/// When the stride is absent it defaults to 1.
53
/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
54
/// where size is the size of the array dimension. When the lower-bound is
55
/// absent it defaults to 0.
56
class OMPArraySectionExpr : public Expr {
57
  enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
58
  Stmt *SubExprs[END_EXPR];
59
  SourceLocation ColonLocFirst;
60
  SourceLocation ColonLocSecond;
61
  SourceLocation RBracketLoc;
62
63
public:
64
  OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
65
                      QualType Type, ExprValueKind VK, ExprObjectKind OK,
66
                      SourceLocation ColonLocFirst,
67
                      SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
68
      : Expr(OMPArraySectionExprClass, Type, VK, OK),
69
        ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
70
10.7k
        RBracketLoc(RBracketLoc) {
71
10.7k
    SubExprs[BASE] = Base;
72
10.7k
    SubExprs[LOWER_BOUND] = LowerBound;
73
10.7k
    SubExprs[LENGTH] = Length;
74
10.7k
    SubExprs[STRIDE] = Stride;
75
10.7k
    setDependence(computeDependence(this));
76
10.7k
  }
77
78
  /// Create an empty array section expression.
79
  explicit OMPArraySectionExpr(EmptyShell Shell)
80
1.88k
      : Expr(OMPArraySectionExprClass, Shell) {}
81
82
  /// An array section can be written only as Base[LowerBound:Length].
83
84
  /// Get base of the array section.
85
32.6k
  Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
86
87.4k
  const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
87
  /// Set base of the array section.
88
1.88k
  void setBase(Expr *E) { SubExprs[BASE] = E; }
89
90
  /// Return original type of the base expression for array section.
91
  static QualType getBaseOriginalType(const Expr *Base);
92
93
  /// Get lower bound of array section.
94
20.6k
  Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
95
9.02k
  const Expr *getLowerBound() const {
96
9.02k
    return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
97
9.02k
  }
98
  /// Set lower bound of the array section.
99
1.88k
  void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
100
101
  /// Get length of array section.
102
22.2k
  Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
103
20.2k
  const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
104
  /// Set length of the array section.
105
1.88k
  void setLength(Expr *E) { SubExprs[LENGTH] = E; }
106
107
  /// Get stride of array section.
108
5.06k
  Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); }
109
0
  const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); }
110
  /// Set length of the array section.
111
1.88k
  void setStride(Expr *E) { SubExprs[STRIDE] = E; }
112
113
25.3k
  SourceLocation getBeginLoc() const LLVM_READONLY {
114
25.3k
    return getBase()->getBeginLoc();
115
25.3k
  }
116
18.4k
  SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
117
118
22.5k
  SourceLocation getColonLocFirst() const { return ColonLocFirst; }
119
1.88k
  void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
120
121
7.23k
  SourceLocation getColonLocSecond() const { return ColonLocSecond; }
122
1.88k
  void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }
123
124
4.87k
  SourceLocation getRBracketLoc() const { return RBracketLoc; }
125
1.88k
  void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
126
127
39.7k
  SourceLocation getExprLoc() const LLVM_READONLY {
128
39.7k
    return getBase()->getExprLoc();
129
39.7k
  }
130
131
393k
  static bool classof(const Stmt *T) {
132
393k
    return T->getStmtClass() == OMPArraySectionExprClass;
133
393k
  }
134
135
3.64k
  child_range children() {
136
3.64k
    return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
137
3.64k
  }
138
139
0
  const_child_range children() const {
140
0
    return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
141
0
  }
142
};
143
144
/// An explicit cast in C or a C-style cast in C++, which uses the syntax
145
/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
146
class OMPArrayShapingExpr final
147
    : public Expr,
148
      private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
149
  friend TrailingObjects;
150
  friend class ASTStmtReader;
151
  friend class ASTStmtWriter;
152
  /// Base node.
153
  SourceLocation LPLoc; /// The location of the left paren
154
  SourceLocation RPLoc; /// The location of the right paren
155
  unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
156
157
  /// Construct full expression.
158
  OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
159
                      SourceLocation R, ArrayRef<Expr *> Dims);
160
161
  /// Construct an empty expression.
162
  explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
163
44
      : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
164
165
  /// Sets the dimensions for the array shaping.
166
  void setDimensions(ArrayRef<Expr *> Dims);
167
168
  /// Sets the base expression for array shaping operation.
169
201
  void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
170
171
  /// Sets source ranges for the brackets in the array shaping operation.
172
  void setBracketsRanges(ArrayRef<SourceRange> BR);
173
174
307
  unsigned numTrailingObjects(OverloadToken<Expr *>) const {
175
    // Add an extra one for the base expression.
176
307
    return NumDims + 1;
177
307
  }
178
179
0
  unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
180
0
    return NumDims;
181
0
  }
182
183
public:
184
  static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
185
                                     Expr *Op, SourceLocation L,
186
                                     SourceLocation R, ArrayRef<Expr *> Dims,
187
                                     ArrayRef<SourceRange> BracketRanges);
188
189
  static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
190
                                          unsigned NumDims);
191
192
106
  SourceLocation getLParenLoc() const { return LPLoc; }
193
44
  void setLParenLoc(SourceLocation L) { LPLoc = L; }
194
195
106
  SourceLocation getRParenLoc() const { return RPLoc; }
196
44
  void setRParenLoc(SourceLocation L) { RPLoc = L; }
197
198
734
  SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
199
265
  SourceLocation getEndLoc() const LLVM_READONLY {
200
265
    return getBase()->getEndLoc();
201
265
  }
202
203
  /// Fetches the dimensions for array shaping expression.
204
425
  ArrayRef<Expr *> getDimensions() const {
205
425
    return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
206
425
  }
207
208
  /// Fetches source ranges for the brackets os the array shaping expression.
209
106
  ArrayRef<SourceRange> getBracketsRanges() const {
210
106
    return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
211
106
  }
212
213
  /// Fetches base expression of array shaping expression.
214
437
  Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
215
403
  const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
216
217
65.9k
  static bool classof(const Stmt *T) {
218
65.9k
    return T->getStmtClass() == OMPArrayShapingExprClass;
219
65.9k
  }
220
221
  // Iterators
222
46
  child_range children() {
223
46
    Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
224
46
    return child_range(Begin, Begin + NumDims + 1);
225
46
  }
226
0
  const_child_range children() const {
227
0
    Stmt *const *Begin =
228
0
        reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
229
0
    return const_child_range(Begin, Begin + NumDims + 1);
230
0
  }
231
};
232
233
/// Helper expressions and declaration for OMPIteratorExpr class for each
234
/// iteration space.
235
struct OMPIteratorHelperData {
236
  /// Internal normalized counter.
237
  VarDecl *CounterVD = nullptr;
238
  /// Normalized upper bound. Normalized loop iterates from 0 to Upper with
239
  /// step 1.
240
  Expr *Upper = nullptr;
241
  /// Update expression for the originally specified iteration variable,
242
  /// calculated as VD = Begin + CounterVD * Step;
243
  Expr *Update = nullptr;
244
  /// Updater for the internal counter: ++CounterVD;
245
  Expr *CounterUpdate = nullptr;
246
};
247
248
/// OpenMP 5.0 [2.1.6 Iterators]
249
/// Iterators are identifiers that expand to multiple values in the clause on
250
/// which they appear.
251
/// The syntax of the iterator modifier is as follows:
252
/// \code
253
/// iterator(iterators-definition)
254
/// \endcode
255
/// where iterators-definition is one of the following:
256
/// \code
257
/// iterator-specifier [, iterators-definition ]
258
/// \endcode
259
/// where iterator-specifier is one of the following:
260
/// \code
261
/// [ iterator-type ] identifier = range-specification
262
/// \endcode
263
/// where identifier is a base language identifier.
264
/// iterator-type is a type name.
265
/// range-specification is of the form begin:end[:step], where begin and end are
266
/// expressions for which their types can be converted to iterator-type and step
267
/// is an integral expression.
268
/// In an iterator-specifier, if the iterator-type is not specified then the
269
/// type of that iterator is of int type.
270
/// The iterator-type must be an integral or pointer type.
271
/// The iterator-type must not be const qualified.
272
class OMPIteratorExpr final
273
    : public Expr,
274
      private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
275
                                    SourceLocation, OMPIteratorHelperData> {
276
public:
277
  /// Iterator range representation begin:end[:step].
278
  struct IteratorRange {
279
    Expr *Begin = nullptr;
280
    Expr *End = nullptr;
281
    Expr *Step = nullptr;
282
  };
283
  /// Iterator definition representation.
284
  struct IteratorDefinition {
285
    Decl *IteratorDecl = nullptr;
286
    IteratorRange Range;
287
    SourceLocation AssignmentLoc;
288
    SourceLocation ColonLoc, SecondColonLoc;
289
  };
290
291
private:
292
  friend TrailingObjects;
293
  friend class ASTStmtReader;
294
  friend class ASTStmtWriter;
295
296
  /// Offset in the list of expressions for subelements of the ranges.
297
  enum class RangeExprOffset {
298
    Begin = 0,
299
    End = 1,
300
    Step = 2,
301
    Total = 3,
302
  };
303
  /// Offset in the list of locations for subelements of colon symbols
304
  /// locations.
305
  enum class RangeLocOffset {
306
    AssignLoc = 0,
307
    FirstColonLoc = 1,
308
    SecondColonLoc = 2,
309
    Total = 3,
310
  };
311
  /// Location of 'iterator' keyword.
312
  SourceLocation IteratorKwLoc;
313
  /// Location of '('.
314
  SourceLocation LPLoc;
315
  /// Location of ')'.
316
  SourceLocation RPLoc;
317
  /// Number of iterator definitions.
318
  unsigned NumIterators = 0;
319
320
  OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc,
321
                  SourceLocation L, SourceLocation R,
322
                  ArrayRef<IteratorDefinition> Data,
323
                  ArrayRef<OMPIteratorHelperData> Helpers);
324
325
  /// Construct an empty expression.
326
  explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators)
327
14
      : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
328
329
  /// Sets basic declaration for the specified iterator definition.
330
  void setIteratorDeclaration(unsigned I, Decl *D);
331
332
  /// Sets the location of the assignment symbol for the specified iterator
333
  /// definition.
334
  void setAssignmentLoc(unsigned I, SourceLocation Loc);
335
336
  /// Sets begin, end and optional step expressions for specified iterator
337
  /// definition.
338
  void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc,
339
                        Expr *End, SourceLocation SecondColonLoc, Expr *Step);
340
341
  /// Sets helpers for the specified iteration space.
342
  void setHelper(unsigned I, const OMPIteratorHelperData &D);
343
344
1.28k
  unsigned numTrailingObjects(OverloadToken<Decl *>) const {
345
1.28k
    return NumIterators;
346
1.28k
  }
347
348
520
  unsigned numTrailingObjects(OverloadToken<Expr *>) const {
349
520
    return NumIterators * static_cast<int>(RangeExprOffset::Total);
350
520
  }
351
352
140
  unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
353
140
    return NumIterators * static_cast<int>(RangeLocOffset::Total);
354
140
  }
355
356
public:
357
  static OMPIteratorExpr *Create(const ASTContext &Context, QualType T,
358
                                 SourceLocation IteratorKwLoc, SourceLocation L,
359
                                 SourceLocation R,
360
                                 ArrayRef<IteratorDefinition> Data,
361
                                 ArrayRef<OMPIteratorHelperData> Helpers);
362
363
  static OMPIteratorExpr *CreateEmpty(const ASTContext &Context,
364
                                      unsigned NumIterators);
365
366
26
  SourceLocation getLParenLoc() const { return LPLoc; }
367
14
  void setLParenLoc(SourceLocation L) { LPLoc = L; }
368
369
26
  SourceLocation getRParenLoc() const { return RPLoc; }
370
14
  void setRParenLoc(SourceLocation L) { RPLoc = L; }
371
372
26
  SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; }
373
14
  void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; }
374
8
  SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; }
375
0
  SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; }
376
377
  /// Gets the iterator declaration for the given iterator.
378
  Decl *getIteratorDecl(unsigned I);
379
6
  const Decl *getIteratorDecl(unsigned I) const {
380
6
    return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I);
381
6
  }
382
383
  /// Gets the iterator range for the given iterator.
384
  IteratorRange getIteratorRange(unsigned I);
385
0
  const IteratorRange getIteratorRange(unsigned I) const {
386
0
    return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I);
387
0
  }
388
389
  /// Gets the location of '=' for the given iterator definition.
390
  SourceLocation getAssignLoc(unsigned I) const;
391
  /// Gets the location of the first ':' in the range for the given iterator
392
  /// definition.
393
  SourceLocation getColonLoc(unsigned I) const;
394
  /// Gets the location of the second ':' (if any) in the range for the given
395
  /// iteratori definition.
396
  SourceLocation getSecondColonLoc(unsigned I) const;
397
398
  /// Returns number of iterator definitions.
399
142
  unsigned numOfIterators() const { return NumIterators; }
400
401
  /// Fetches helper data for the specified iteration space.
402
  OMPIteratorHelperData &getHelper(unsigned I);
403
  const OMPIteratorHelperData &getHelper(unsigned I) const;
404
405
46
  static bool classof(const Stmt *T) {
406
46
    return T->getStmtClass() == OMPIteratorExprClass;
407
46
  }
408
409
  // Iterators
410
24
  child_range children() {
411
24
    Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
412
24
    return child_range(
413
24
        Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
414
24
  }
415
0
  const_child_range children() const {
416
0
    Stmt *const *Begin =
417
0
        reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
418
0
    return const_child_range(
419
0
        Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
420
0
  }
421
};
422
423
} // end namespace clang
424
425
#endif