Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Parse/ParseOpenMP.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
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
/// \file
9
/// This file implements parsing of all OpenMP directives and clauses.
10
///
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/AST/ASTContext.h"
14
#include "clang/AST/OpenMPClause.h"
15
#include "clang/AST/StmtOpenMP.h"
16
#include "clang/Basic/OpenMPKinds.h"
17
#include "clang/Basic/TargetInfo.h"
18
#include "clang/Basic/TokenKinds.h"
19
#include "clang/Parse/ParseDiagnostic.h"
20
#include "clang/Parse/Parser.h"
21
#include "clang/Parse/RAIIObjectsForParser.h"
22
#include "clang/Sema/Scope.h"
23
#include "llvm/ADT/PointerIntPair.h"
24
#include "llvm/ADT/StringSwitch.h"
25
#include "llvm/ADT/UniqueVector.h"
26
#include "llvm/Frontend/OpenMP/OMPAssume.h"
27
#include "llvm/Frontend/OpenMP/OMPContext.h"
28
29
using namespace clang;
30
using namespace llvm::omp;
31
32
//===----------------------------------------------------------------------===//
33
// OpenMP declarative directives.
34
//===----------------------------------------------------------------------===//
35
36
namespace {
37
enum OpenMPDirectiveKindEx {
38
  OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
39
  OMPD_data,
40
  OMPD_declare,
41
  OMPD_end,
42
  OMPD_end_declare,
43
  OMPD_enter,
44
  OMPD_exit,
45
  OMPD_point,
46
  OMPD_reduction,
47
  OMPD_target_enter,
48
  OMPD_target_exit,
49
  OMPD_update,
50
  OMPD_distribute_parallel,
51
  OMPD_teams_distribute_parallel,
52
  OMPD_target_teams_distribute_parallel,
53
  OMPD_mapper,
54
  OMPD_variant,
55
  OMPD_begin,
56
  OMPD_begin_declare,
57
};
58
59
// Helper to unify the enum class OpenMPDirectiveKind with its extension
60
// the OpenMPDirectiveKindEx enum which allows to use them together as if they
61
// are unsigned values.
62
struct OpenMPDirectiveKindExWrapper {
63
8.62M
  OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
64
3.76M
  OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
65
715k
  bool operator==(OpenMPDirectiveKindExWrapper V) const {
66
715k
    return Value == V.Value;
67
715k
  }
68
16.3M
  bool operator!=(OpenMPDirectiveKindExWrapper V) const {
69
16.3M
    return Value != V.Value;
70
16.3M
  }
71
1.78M
  bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
72
1.45M
  bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
73
0
  bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
74
1.73M
  operator unsigned() const { return Value; }
75
826k
  operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
76
  unsigned Value;
77
};
78
79
class DeclDirectiveListParserHelper final {
80
  SmallVector<Expr *, 4> Identifiers;
81
  Parser *P;
82
  OpenMPDirectiveKind Kind;
83
84
public:
85
  DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
86
3.56k
      : P(P), Kind(Kind) {}
87
3.74k
  void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
88
3.74k
    ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
89
3.74k
        P->getCurScope(), SS, NameInfo, Kind);
90
3.74k
    if (Res.isUsable())
91
3.64k
      Identifiers.push_back(Res.get());
92
3.74k
  }
93
3.47k
  llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
94
};
95
} // namespace
96
97
// Map token string to extended OMP token kind that are
98
// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
99
1.44M
static unsigned getOpenMPDirectiveKindEx(StringRef S) {
100
1.44M
  OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
101
1.44M
  if (DKind != OMPD_unknown)
102
906k
    return DKind;
103
104
539k
  return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
105
539k
      .Case("cancellation", OMPD_cancellation)
106
539k
      .Case("data", OMPD_data)
107
539k
      .Case("declare", OMPD_declare)
108
539k
      .Case("end", OMPD_end)
109
539k
      .Case("enter", OMPD_enter)
110
539k
      .Case("exit", OMPD_exit)
111
539k
      .Case("point", OMPD_point)
112
539k
      .Case("reduction", OMPD_reduction)
113
539k
      .Case("update", OMPD_update)
114
539k
      .Case("mapper", OMPD_mapper)
115
539k
      .Case("variant", OMPD_variant)
116
539k
      .Case("begin", OMPD_begin)
117
539k
      .Default(OMPD_unknown);
118
1.44M
}
119
120
556k
static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
121
  // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
122
  // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
123
  // TODO: add other combined directives in topological order.
124
556k
  static const OpenMPDirectiveKindExWrapper F[][3] = {
125
556k
      {OMPD_begin, OMPD_declare, OMPD_begin_declare},
126
556k
      {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
127
556k
      {OMPD_end, OMPD_declare, OMPD_end_declare},
128
556k
      {OMPD_end, OMPD_assumes, OMPD_end_assumes},
129
556k
      {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
130
556k
      {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
131
556k
      {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
132
556k
      {OMPD_declare, OMPD_simd, OMPD_declare_simd},
133
556k
      {OMPD_declare, OMPD_target, OMPD_declare_target},
134
556k
      {OMPD_declare, OMPD_variant, OMPD_declare_variant},
135
556k
      {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
136
556k
      {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
137
556k
      {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
138
556k
      {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
139
556k
      {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
140
556k
      {OMPD_distribute_parallel_for, OMPD_simd,
141
556k
       OMPD_distribute_parallel_for_simd},
142
556k
      {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
143
556k
      {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
144
556k
      {OMPD_target, OMPD_data, OMPD_target_data},
145
556k
      {OMPD_target, OMPD_enter, OMPD_target_enter},
146
556k
      {OMPD_target, OMPD_exit, OMPD_target_exit},
147
556k
      {OMPD_target, OMPD_update, OMPD_target_update},
148
556k
      {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
149
556k
      {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
150
556k
      {OMPD_for, OMPD_simd, OMPD_for_simd},
151
556k
      {OMPD_parallel, OMPD_for, OMPD_parallel_for},
152
556k
      {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
153
556k
      {OMPD_parallel, OMPD_loop, OMPD_parallel_loop},
154
556k
      {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
155
556k
      {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
156
556k
      {OMPD_target, OMPD_parallel, OMPD_target_parallel},
157
556k
      {OMPD_target, OMPD_simd, OMPD_target_simd},
158
556k
      {OMPD_target_parallel, OMPD_loop, OMPD_target_parallel_loop},
159
556k
      {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
160
556k
      {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
161
556k
      {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
162
556k
      {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
163
556k
      {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
164
556k
      {OMPD_teams_distribute_parallel, OMPD_for,
165
556k
       OMPD_teams_distribute_parallel_for},
166
556k
      {OMPD_teams_distribute_parallel_for, OMPD_simd,
167
556k
       OMPD_teams_distribute_parallel_for_simd},
168
556k
      {OMPD_teams, OMPD_loop, OMPD_teams_loop},
169
556k
      {OMPD_target, OMPD_teams, OMPD_target_teams},
170
556k
      {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
171
556k
      {OMPD_target_teams, OMPD_loop, OMPD_target_teams_loop},
172
556k
      {OMPD_target_teams_distribute, OMPD_parallel,
173
556k
       OMPD_target_teams_distribute_parallel},
174
556k
      {OMPD_target_teams_distribute, OMPD_simd,
175
556k
       OMPD_target_teams_distribute_simd},
176
556k
      {OMPD_target_teams_distribute_parallel, OMPD_for,
177
556k
       OMPD_target_teams_distribute_parallel_for},
178
556k
      {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
179
556k
       OMPD_target_teams_distribute_parallel_for_simd},
180
556k
      {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
181
556k
      {OMPD_masked, OMPD_taskloop, OMPD_masked_taskloop},
182
556k
      {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
183
556k
      {OMPD_masked_taskloop, OMPD_simd, OMPD_masked_taskloop_simd},
184
556k
      {OMPD_parallel, OMPD_master, OMPD_parallel_master},
185
556k
      {OMPD_parallel, OMPD_masked, OMPD_parallel_masked},
186
556k
      {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
187
556k
      {OMPD_parallel_masked, OMPD_taskloop, OMPD_parallel_masked_taskloop},
188
556k
      {OMPD_parallel_master_taskloop, OMPD_simd,
189
556k
       OMPD_parallel_master_taskloop_simd},
190
556k
      {OMPD_parallel_masked_taskloop, OMPD_simd,
191
556k
       OMPD_parallel_masked_taskloop_simd}};
192
556k
  enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
193
556k
  Token Tok = P.getCurToken();
194
556k
  OpenMPDirectiveKindExWrapper DKind =
195
556k
      Tok.isAnnotation()
196
556k
          ? 
static_cast<unsigned>(OMPD_unknown)473
197
556k
          : 
getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok))555k
;
198
556k
  if (DKind == OMPD_unknown)
199
275k
    return OMPD_unknown;
200
201
16.5M
  
for (unsigned I = 0; 281k
I < llvm::array_lengthof(F);
++I16.3M
) {
202
16.3M
    if (DKind != F[I][0])
203
15.0M
      continue;
204
205
1.23M
    Tok = P.getPreprocessor().LookAhead(0);
206
1.23M
    OpenMPDirectiveKindExWrapper SDKind =
207
1.23M
        Tok.isAnnotation()
208
1.23M
            ? 
static_cast<unsigned>(OMPD_unknown)342k
209
1.23M
            : 
getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok))890k
;
210
1.23M
    if (SDKind == OMPD_unknown)
211
517k
      continue;
212
213
715k
    if (SDKind == F[I][1]) {
214
288k
      P.ConsumeToken();
215
288k
      DKind = F[I][2];
216
288k
    }
217
715k
  }
218
281k
  return unsigned(DKind) < llvm::omp::Directive_enumSize
219
281k
             ? 
static_cast<OpenMPDirectiveKind>(DKind)281k
220
281k
             : 
OMPD_unknown36
;
221
556k
}
222
223
688
static DeclarationName parseOpenMPReductionId(Parser &P) {
224
688
  Token Tok = P.getCurToken();
225
688
  Sema &Actions = P.getActions();
226
688
  OverloadedOperatorKind OOK = OO_None;
227
  // Allow to use 'operator' keyword for C++ operators
228
688
  bool WithOperator = false;
229
688
  if (Tok.is(tok::kw_operator)) {
230
52
    P.ConsumeToken();
231
52
    Tok = P.getCurToken();
232
52
    WithOperator = true;
233
52
  }
234
688
  switch (Tok.getKind()) {
235
98
  case tok::plus: // '+'
236
98
    OOK = OO_Plus;
237
98
    break;
238
16
  case tok::minus: // '-'
239
16
    OOK = OO_Minus;
240
16
    break;
241
12
  case tok::star: // '*'
242
12
    OOK = OO_Star;
243
12
    break;
244
18
  case tok::amp: // '&'
245
18
    OOK = OO_Amp;
246
18
    break;
247
10
  case tok::pipe: // '|'
248
10
    OOK = OO_Pipe;
249
10
    break;
250
8
  case tok::caret: // '^'
251
8
    OOK = OO_Caret;
252
8
    break;
253
24
  case tok::ampamp: // '&&'
254
24
    OOK = OO_AmpAmp;
255
24
    break;
256
8
  case tok::pipepipe: // '||'
257
8
    OOK = OO_PipePipe;
258
8
    break;
259
454
  case tok::identifier: // identifier
260
454
    if (!WithOperator)
261
454
      break;
262
454
    
LLVM_FALLTHROUGH0
;0
263
40
  default:
264
40
    P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
265
40
    P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
266
40
                Parser::StopBeforeMatch);
267
40
    return DeclarationName();
268
688
  }
269
648
  P.ConsumeToken();
270
648
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
271
648
  return OOK == OO_None ? 
DeclNames.getIdentifier(Tok.getIdentifierInfo())454
272
648
                        : 
DeclNames.getCXXOperatorName(OOK)194
;
273
688
}
274
275
/// Parse 'omp declare reduction' construct.
276
///
277
///       declare-reduction-directive:
278
///        annot_pragma_openmp 'declare' 'reduction'
279
///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
280
///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
281
///        annot_pragma_openmp_end
282
/// <reduction_id> is either a base language identifier or one of the following
283
/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
284
///
285
Parser::DeclGroupPtrTy
286
704
Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
287
  // Parse '('.
288
704
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
289
704
  if (T.expectAndConsume(
290
704
          diag::err_expected_lparen_after,
291
704
          getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
292
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
293
16
    return DeclGroupPtrTy();
294
16
  }
295
296
688
  DeclarationName Name = parseOpenMPReductionId(*this);
297
688
  if (Name.isEmpty() && 
Tok.is(tok::annot_pragma_openmp_end)40
)
298
32
    return DeclGroupPtrTy();
299
300
  // Consume ':'.
301
656
  bool IsCorrect = !ExpectAndConsume(tok::colon);
302
303
656
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)16
)
304
8
    return DeclGroupPtrTy();
305
306
648
  IsCorrect = IsCorrect && 
!Name.isEmpty()640
;
307
308
648
  if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
309
16
    Diag(Tok.getLocation(), diag::err_expected_type);
310
16
    IsCorrect = false;
311
16
  }
312
313
648
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)24
)
314
16
    return DeclGroupPtrTy();
315
316
632
  SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
317
  // Parse list of types until ':' token.
318
752
  do {
319
752
    ColonProtectionRAIIObject ColonRAII(*this);
320
752
    SourceRange Range;
321
752
    TypeResult TR = ParseTypeName(&Range, DeclaratorContext::Prototype, AS);
322
752
    if (TR.isUsable()) {
323
720
      QualType ReductionType =
324
720
          Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
325
720
      if (!ReductionType.isNull()) {
326
682
        ReductionTypes.push_back(
327
682
            std::make_pair(ReductionType, Range.getBegin()));
328
682
      }
329
720
    } else {
330
32
      SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
331
32
                StopBeforeMatch);
332
32
    }
333
334
752
    if (Tok.is(tok::colon) || 
Tok.is(tok::annot_pragma_openmp_end)144
)
335
632
      break;
336
337
    // Consume ','.
338
120
    if (ExpectAndConsume(tok::comma)) {
339
8
      IsCorrect = false;
340
8
      if (Tok.is(tok::annot_pragma_openmp_end)) {
341
0
        Diag(Tok.getLocation(), diag::err_expected_type);
342
0
        return DeclGroupPtrTy();
343
0
      }
344
8
    }
345
120
  } while (Tok.isNot(tok::annot_pragma_openmp_end));
346
347
632
  if (ReductionTypes.empty()) {
348
46
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
349
46
    return DeclGroupPtrTy();
350
46
  }
351
352
586
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
353
8
    return DeclGroupPtrTy();
354
355
  // Consume ':'.
356
578
  if (ExpectAndConsume(tok::colon))
357
8
    IsCorrect = false;
358
359
578
  if (Tok.is(tok::annot_pragma_openmp_end)) {
360
32
    Diag(Tok.getLocation(), diag::err_expected_expression);
361
32
    return DeclGroupPtrTy();
362
32
  }
363
364
546
  DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
365
546
      getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
366
367
  // Parse <combiner> expression and then parse initializer if any for each
368
  // correct type.
369
546
  unsigned I = 0, E = ReductionTypes.size();
370
634
  for (Decl *D : DRD.get()) {
371
634
    TentativeParsingAction TPA(*this);
372
634
    ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
373
634
                                    Scope::CompoundStmtScope |
374
634
                                    Scope::OpenMPDirectiveScope);
375
    // Parse <combiner> expression.
376
634
    Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
377
634
    ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
378
634
        ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
379
634
    Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
380
381
634
    if (CombinerResult.isInvalid() && 
Tok.isNot(tok::r_paren)52
&&
382
634
        
Tok.isNot(tok::annot_pragma_openmp_end)0
) {
383
0
      TPA.Commit();
384
0
      IsCorrect = false;
385
0
      break;
386
0
    }
387
634
    IsCorrect = !T.consumeClose() && IsCorrect && 
CombinerResult.isUsable()618
;
388
634
    ExprResult InitializerResult;
389
634
    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
390
      // Parse <initializer> expression.
391
268
      if (Tok.is(tok::identifier) &&
392
268
          
Tok.getIdentifierInfo()->isStr("initializer")252
) {
393
252
        ConsumeToken();
394
252
      } else {
395
16
        Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
396
16
        TPA.Commit();
397
16
        IsCorrect = false;
398
16
        break;
399
16
      }
400
      // Parse '('.
401
252
      BalancedDelimiterTracker T(*this, tok::l_paren,
402
252
                                 tok::annot_pragma_openmp_end);
403
252
      IsCorrect =
404
252
          !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
405
252
          
IsCorrect228
;
406
252
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
407
244
        ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
408
244
                                        Scope::CompoundStmtScope |
409
244
                                        Scope::OpenMPDirectiveScope);
410
        // Parse expression.
411
244
        VarDecl *OmpPrivParm =
412
244
            Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
413
244
                                                                D);
414
        // Check if initializer is omp_priv <init_expr> or something else.
415
244
        if (Tok.is(tok::identifier) &&
416
244
            
Tok.getIdentifierInfo()->isStr("omp_priv")220
) {
417
141
          ConsumeToken();
418
141
          ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
419
141
        } else {
420
103
          InitializerResult = Actions.ActOnFinishFullExpr(
421
103
              ParseAssignmentExpression().get(), D->getLocation(),
422
103
              /*DiscardedValue*/ false);
423
103
        }
424
244
        Actions.ActOnOpenMPDeclareReductionInitializerEnd(
425
244
            D, InitializerResult.get(), OmpPrivParm);
426
244
        if (InitializerResult.isInvalid() && 
Tok.isNot(tok::r_paren)32
&&
427
244
            
Tok.isNot(tok::annot_pragma_openmp_end)16
) {
428
12
          TPA.Commit();
429
12
          IsCorrect = false;
430
12
          break;
431
12
        }
432
232
        IsCorrect =
433
232
            !T.consumeClose() && 
IsCorrect194
&&
!InitializerResult.isInvalid()194
;
434
232
      }
435
252
    }
436
437
606
    ++I;
438
    // Revert parsing if not the last type, otherwise accept it, we're done with
439
    // parsing.
440
606
    if (I != E)
441
88
      TPA.Revert();
442
518
    else
443
518
      TPA.Commit();
444
606
  }
445
546
  return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
446
546
                                                         IsCorrect);
447
578
}
448
449
141
void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
450
  // Parse declarator '=' initializer.
451
  // If a '==' or '+=' is found, suggest a fixit to '='.
452
141
  if (isTokenEqualOrEqualTypo()) {
453
115
    ConsumeToken();
454
455
115
    if (Tok.is(tok::code_completion)) {
456
0
      cutOffParsing();
457
0
      Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
458
0
      Actions.FinalizeDeclaration(OmpPrivParm);
459
0
      return;
460
0
    }
461
462
115
    PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
463
115
    ExprResult Init = ParseInitializer();
464
465
115
    if (Init.isInvalid()) {
466
2
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
467
2
      Actions.ActOnInitializerError(OmpPrivParm);
468
113
    } else {
469
113
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
470
113
                                   /*DirectInit=*/false);
471
113
    }
472
115
  } else 
if (26
Tok.is(tok::l_paren)26
) {
473
    // Parse C++ direct initializer: '(' expression-list ')'
474
0
    BalancedDelimiterTracker T(*this, tok::l_paren);
475
0
    T.consumeOpen();
476
477
0
    ExprVector Exprs;
478
0
    CommaLocsTy CommaLocs;
479
480
0
    SourceLocation LParLoc = T.getOpenLocation();
481
0
    auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
482
0
      QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
483
0
          OmpPrivParm->getType()->getCanonicalTypeInternal(),
484
0
          OmpPrivParm->getLocation(), Exprs, LParLoc, /*Braced=*/false);
485
0
      CalledSignatureHelp = true;
486
0
      return PreferredType;
487
0
    };
488
0
    if (ParseExpressionList(Exprs, CommaLocs, [&] {
489
0
          PreferredType.enterFunctionArgument(Tok.getLocation(),
490
0
                                              RunSignatureHelp);
491
0
        })) {
492
0
      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
493
0
        RunSignatureHelp();
494
0
      Actions.ActOnInitializerError(OmpPrivParm);
495
0
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
496
0
    } else {
497
      // Match the ')'.
498
0
      SourceLocation RLoc = Tok.getLocation();
499
0
      if (!T.consumeClose())
500
0
        RLoc = T.getCloseLocation();
501
502
0
      assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
503
0
             "Unexpected number of commas!");
504
505
0
      ExprResult Initializer =
506
0
          Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
507
0
      Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
508
0
                                   /*DirectInit=*/true);
509
0
    }
510
26
  } else if (getLangOpts().CPlusPlus11 && 
Tok.is(tok::l_brace)16
) {
511
    // Parse C++0x braced-init-list.
512
0
    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
513
514
0
    ExprResult Init(ParseBraceInitializer());
515
516
0
    if (Init.isInvalid()) {
517
0
      Actions.ActOnInitializerError(OmpPrivParm);
518
0
    } else {
519
0
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
520
0
                                   /*DirectInit=*/true);
521
0
    }
522
26
  } else {
523
26
    Actions.ActOnUninitializedDecl(OmpPrivParm);
524
26
  }
525
141
}
526
527
/// Parses 'omp declare mapper' directive.
528
///
529
///       declare-mapper-directive:
530
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
531
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
532
///         annot_pragma_openmp_end
533
/// <mapper-identifier> and <var> are base language identifiers.
534
///
535
Parser::DeclGroupPtrTy
536
395
Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
537
395
  bool IsCorrect = true;
538
  // Parse '('
539
395
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
540
395
  if (T.expectAndConsume(diag::err_expected_lparen_after,
541
395
                         getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
542
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
543
16
    return DeclGroupPtrTy();
544
16
  }
545
546
  // Parse <mapper-identifier>
547
379
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
548
379
  DeclarationName MapperId;
549
379
  if (PP.LookAhead(0).is(tok::colon)) {
550
287
    if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)40
) {
551
8
      Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
552
8
      IsCorrect = false;
553
279
    } else {
554
279
      MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
555
279
    }
556
287
    ConsumeToken();
557
    // Consume ':'.
558
287
    ExpectAndConsume(tok::colon);
559
287
  } else {
560
    // If no mapper identifier is provided, its name is "default" by default
561
92
    MapperId =
562
92
        DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
563
92
  }
564
565
379
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
566
0
    return DeclGroupPtrTy();
567
568
  // Parse <type> <var>
569
379
  DeclarationName VName;
570
379
  QualType MapperType;
571
379
  SourceRange Range;
572
379
  TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
573
379
  if (ParsedType.isUsable())
574
327
    MapperType =
575
327
        Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
576
379
  if (MapperType.isNull())
577
60
    IsCorrect = false;
578
379
  if (!IsCorrect) {
579
68
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
580
68
    return DeclGroupPtrTy();
581
68
  }
582
583
  // Consume ')'.
584
311
  IsCorrect &= !T.consumeClose();
585
311
  if (!IsCorrect) {
586
8
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
587
8
    return DeclGroupPtrTy();
588
8
  }
589
590
  // Enter scope.
591
303
  DeclarationNameInfo DirName;
592
303
  SourceLocation Loc = Tok.getLocation();
593
303
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
594
303
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
595
303
  ParseScope OMPDirectiveScope(this, ScopeFlags);
596
303
  Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
597
598
  // Add the mapper variable declaration.
599
303
  ExprResult MapperVarRef = Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
600
303
      getCurScope(), MapperType, Range.getBegin(), VName);
601
602
  // Parse map clauses.
603
303
  SmallVector<OMPClause *, 6> Clauses;
604
620
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
605
317
    OpenMPClauseKind CKind = Tok.isAnnotation()
606
317
                                 ? 
OMPC_unknown0
607
317
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
608
317
    Actions.StartOpenMPClause(CKind);
609
317
    OMPClause *Clause =
610
317
        ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
611
317
    if (Clause)
612
299
      Clauses.push_back(Clause);
613
18
    else
614
18
      IsCorrect = false;
615
    // Skip ',' if any.
616
317
    if (Tok.is(tok::comma))
617
0
      ConsumeToken();
618
317
    Actions.EndOpenMPClause();
619
317
  }
620
303
  if (Clauses.empty()) {
621
16
    Diag(Tok, diag::err_omp_expected_clause)
622
16
        << getOpenMPDirectiveName(OMPD_declare_mapper);
623
16
    IsCorrect = false;
624
16
  }
625
626
  // Exit scope.
627
303
  Actions.EndOpenMPDSABlock(nullptr);
628
303
  OMPDirectiveScope.Exit();
629
303
  DeclGroupPtrTy DG = Actions.ActOnOpenMPDeclareMapperDirective(
630
303
      getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
631
303
      Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
632
303
  if (!IsCorrect)
633
26
    return DeclGroupPtrTy();
634
635
277
  return DG;
636
303
}
637
638
TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
639
                                                   DeclarationName &Name,
640
379
                                                   AccessSpecifier AS) {
641
  // Parse the common declaration-specifiers piece.
642
379
  Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
643
379
  DeclSpec DS(AttrFactory);
644
379
  ParseSpecifierQualifierList(DS, AS, DSC);
645
646
  // Parse the declarator.
647
379
  DeclaratorContext Context = DeclaratorContext::Prototype;
648
379
  Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), Context);
649
379
  ParseDeclarator(DeclaratorInfo);
650
379
  Range = DeclaratorInfo.getSourceRange();
651
379
  if (DeclaratorInfo.getIdentifier() == nullptr) {
652
32
    Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
653
32
    return true;
654
32
  }
655
347
  Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
656
657
347
  return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
658
379
}
659
660
namespace {
661
/// RAII that recreates function context for correct parsing of clauses of
662
/// 'declare simd' construct.
663
/// OpenMP, 2.8.2 declare simd Construct
664
/// The expressions appearing in the clauses of this directive are evaluated in
665
/// the scope of the arguments of the function declaration or definition.
666
class FNContextRAII final {
667
  Parser &P;
668
  Sema::CXXThisScopeRAII *ThisScope;
669
  Parser::MultiParseScope Scopes;
670
  bool HasFunScope = false;
671
  FNContextRAII() = delete;
672
  FNContextRAII(const FNContextRAII &) = delete;
673
  FNContextRAII &operator=(const FNContextRAII &) = delete;
674
675
public:
676
2.65k
  FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P), Scopes(P) {
677
2.65k
    Decl *D = *Ptr.get().begin();
678
2.65k
    NamedDecl *ND = dyn_cast<NamedDecl>(D);
679
2.65k
    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
680
2.65k
    Sema &Actions = P.getActions();
681
682
    // Allow 'this' within late-parsed attributes.
683
2.65k
    ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
684
2.65k
                                           ND && 
ND->isCXXInstanceMember()2.64k
);
685
686
    // If the Decl is templatized, add template parameters to scope.
687
    // FIXME: Track CurTemplateDepth?
688
2.65k
    P.ReenterTemplateScopes(Scopes, D);
689
690
    // If the Decl is on a function, add function parameters to the scope.
691
2.65k
    if (D->isFunctionOrFunctionTemplate()) {
692
2.63k
      HasFunScope = true;
693
2.63k
      Scopes.Enter(Scope::FnScope | Scope::DeclScope |
694
2.63k
                   Scope::CompoundStmtScope);
695
2.63k
      Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
696
2.63k
    }
697
2.65k
  }
698
2.65k
  ~FNContextRAII() {
699
2.65k
    if (HasFunScope)
700
2.63k
      P.getActions().ActOnExitFunctionContext();
701
2.65k
    delete ThisScope;
702
2.65k
  }
703
};
704
} // namespace
705
706
/// Parses clauses for 'declare simd' directive.
707
///    clause:
708
///      'inbranch' | 'notinbranch'
709
///      'simdlen' '(' <expr> ')'
710
///      { 'uniform' '(' <argument_list> ')' }
711
///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
712
///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
713
static bool parseDeclareSimdClauses(
714
    Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
715
    SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
716
    SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
717
524
    SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
718
524
  SourceRange BSRange;
719
524
  const Token &Tok = P.getCurToken();
720
524
  bool IsError = false;
721
1.31k
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
722
800
    if (Tok.isNot(tok::identifier))
723
6
      break;
724
794
    OMPDeclareSimdDeclAttr::BranchStateTy Out;
725
794
    IdentifierInfo *II = Tok.getIdentifierInfo();
726
794
    StringRef ClauseName = II->getName();
727
    // Parse 'inranch|notinbranch' clauses.
728
794
    if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
729
140
      if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && 
BS != Out12
) {
730
4
        P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
731
4
            << ClauseName
732
4
            << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
733
4
        IsError = true;
734
4
      }
735
140
      BS = Out;
736
140
      BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
737
140
      P.ConsumeToken();
738
654
    } else if (ClauseName.equals("simdlen")) {
739
172
      if (SimdLen.isUsable()) {
740
2
        P.Diag(Tok, diag::err_omp_more_one_clause)
741
2
            << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
742
2
        IsError = true;
743
2
      }
744
172
      P.ConsumeToken();
745
172
      SourceLocation RLoc;
746
172
      SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
747
172
      if (SimdLen.isInvalid())
748
18
        IsError = true;
749
482
    } else {
750
482
      OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
751
482
      if (CKind == OMPC_uniform || 
CKind == OMPC_aligned420
||
752
482
          
CKind == OMPC_linear286
) {
753
480
        Sema::OpenMPVarListDataTy Data;
754
480
        SmallVectorImpl<Expr *> *Vars = &Uniforms;
755
480
        if (CKind == OMPC_aligned) {
756
134
          Vars = &Aligneds;
757
346
        } else if (CKind == OMPC_linear) {
758
284
          Data.ExtraModifier = OMPC_LINEAR_val;
759
284
          Vars = &Linears;
760
284
        }
761
762
480
        P.ConsumeToken();
763
480
        if (P.ParseOpenMPVarList(OMPD_declare_simd,
764
480
                                 getOpenMPClauseKind(ClauseName), *Vars, Data))
765
36
          IsError = true;
766
480
        if (CKind == OMPC_aligned) {
767
134
          Alignments.append(Aligneds.size() - Alignments.size(),
768
134
                            Data.DepModOrTailExpr);
769
346
        } else if (CKind == OMPC_linear) {
770
284
          assert(0 <= Data.ExtraModifier &&
771
284
                 Data.ExtraModifier <= OMPC_LINEAR_unknown &&
772
284
                 "Unexpected linear modifier.");
773
284
          if (P.getActions().CheckOpenMPLinearModifier(
774
284
                  static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
775
284
                  Data.ExtraModifierLoc))
776
2
            Data.ExtraModifier = OMPC_LINEAR_val;
777
284
          LinModifiers.append(Linears.size() - LinModifiers.size(),
778
284
                              Data.ExtraModifier);
779
284
          Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr);
780
284
        }
781
480
      } else
782
        // TODO: add parsing of other clauses.
783
2
        break;
784
482
    }
785
    // Skip ',' if any.
786
792
    if (Tok.is(tok::comma))
787
14
      P.ConsumeToken();
788
792
  }
789
524
  return IsError;
790
524
}
791
792
/// Parse clauses for '#pragma omp declare simd'.
793
Parser::DeclGroupPtrTy
794
Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
795
524
                                   CachedTokens &Toks, SourceLocation Loc) {
796
524
  PP.EnterToken(Tok, /*IsReinject*/ true);
797
524
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
798
524
                      /*IsReinject*/ true);
799
  // Consume the previously pushed token.
800
524
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
801
524
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
802
803
524
  FNContextRAII FnContext(*this, Ptr);
804
524
  OMPDeclareSimdDeclAttr::BranchStateTy BS =
805
524
      OMPDeclareSimdDeclAttr::BS_Undefined;
806
524
  ExprResult Simdlen;
807
524
  SmallVector<Expr *, 4> Uniforms;
808
524
  SmallVector<Expr *, 4> Aligneds;
809
524
  SmallVector<Expr *, 4> Alignments;
810
524
  SmallVector<Expr *, 4> Linears;
811
524
  SmallVector<unsigned, 4> LinModifiers;
812
524
  SmallVector<Expr *, 4> Steps;
813
524
  bool IsError =
814
524
      parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
815
524
                              Alignments, Linears, LinModifiers, Steps);
816
524
  skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
817
  // Skip the last annot_pragma_openmp_end.
818
524
  SourceLocation EndLoc = ConsumeAnnotationToken();
819
524
  if (IsError)
820
54
    return Ptr;
821
470
  return Actions.ActOnOpenMPDeclareSimdDirective(
822
470
      Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
823
470
      LinModifiers, Steps, SourceRange(Loc, EndLoc));
824
524
}
825
826
namespace {
827
/// Constant used in the diagnostics to distinguish the levels in an OpenMP
828
/// contexts: selector-set={selector(trait, ...), ...}, ....
829
enum OMPContextLvl {
830
  CONTEXT_SELECTOR_SET_LVL = 0,
831
  CONTEXT_SELECTOR_LVL = 1,
832
  CONTEXT_TRAIT_LVL = 2,
833
};
834
835
27
static StringRef stringLiteralParser(Parser &P) {
836
27
  ExprResult Res = P.ParseStringLiteralExpression(true);
837
27
  return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : 
""0
;
838
27
}
839
840
static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
841
9.32k
                                       OMPContextLvl Lvl) {
842
9.32k
  if (Tok.is(tok::identifier) || 
Tok.is(tok::kw_for)203
) {
843
9.16k
    llvm::SmallString<16> Buffer;
844
9.16k
    StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
845
9.16k
    (void)P.ConsumeToken();
846
9.16k
    return Name;
847
9.16k
  }
848
849
155
  if (tok::isStringLiteral(Tok.getKind()))
850
27
    return stringLiteralParser(P);
851
852
128
  P.Diag(Tok.getLocation(),
853
128
         diag::warn_omp_declare_variant_string_literal_or_identifier)
854
128
      << Lvl;
855
128
  return "";
856
155
}
857
858
static bool checkForDuplicates(Parser &P, StringRef Name,
859
                               SourceLocation NameLoc,
860
                               llvm::StringMap<SourceLocation> &Seen,
861
9.02k
                               OMPContextLvl Lvl) {
862
9.02k
  auto Res = Seen.try_emplace(Name, NameLoc);
863
9.02k
  if (Res.second)
864
9.00k
    return false;
865
866
  // Each trait-set-selector-name, trait-selector-name and trait-name can
867
  // only be specified once.
868
22
  P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
869
22
      << Lvl << Name;
870
22
  P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
871
22
      << Lvl << Name;
872
22
  return true;
873
9.02k
}
874
} // namespace
875
876
void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
877
                                       llvm::omp::TraitSet Set,
878
                                       llvm::omp::TraitSelector Selector,
879
3.41k
                                       llvm::StringMap<SourceLocation> &Seen) {
880
3.41k
  TIProperty.Kind = TraitProperty::invalid;
881
882
3.41k
  SourceLocation NameLoc = Tok.getLocation();
883
3.41k
  StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
884
3.41k
  if (Name.empty()) {
885
60
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
886
60
        << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
887
60
    return;
888
60
  }
889
890
3.35k
  TIProperty.RawString = Name;
891
3.35k
  TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
892
3.35k
  if (TIProperty.Kind != TraitProperty::invalid) {
893
3.34k
    if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
894
6
      TIProperty.Kind = TraitProperty::invalid;
895
3.34k
    return;
896
3.34k
  }
897
898
  // It follows diagnosis and helping notes.
899
  // FIXME: We should move the diagnosis string generation into libFrontend.
900
14
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
901
14
      << Name << getOpenMPContextTraitSelectorName(Selector)
902
14
      << getOpenMPContextTraitSetName(Set);
903
904
14
  TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
905
14
  if (SetForName != TraitSet::invalid) {
906
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
907
0
        << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
908
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
909
0
        << Name << "<selector-name>"
910
0
        << "(<property-name>)";
911
0
    return;
912
0
  }
913
14
  TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
914
14
  if (SelectorForName != TraitSelector::invalid) {
915
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
916
0
        << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
917
0
    bool AllowsTraitScore = false;
918
0
    bool RequiresProperty = false;
919
0
    isValidTraitSelectorForTraitSet(
920
0
        SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
921
0
        AllowsTraitScore, RequiresProperty);
922
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
923
0
        << getOpenMPContextTraitSetName(
924
0
               getOpenMPContextTraitSetForSelector(SelectorForName))
925
0
        << Name << (RequiresProperty ? "(<property-name>)" : "");
926
0
    return;
927
0
  }
928
14
  for (const auto &PotentialSet :
929
14
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
930
48
        TraitSet::device}) {
931
48
    TraitProperty PropertyForName =
932
48
        getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
933
48
    if (PropertyForName == TraitProperty::invalid)
934
40
      continue;
935
8
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
936
8
        << getOpenMPContextTraitSetName(
937
8
               getOpenMPContextTraitSetForProperty(PropertyForName))
938
8
        << getOpenMPContextTraitSelectorName(
939
8
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
940
8
        << ("(" + Name + ")").str();
941
8
    return;
942
48
  }
943
6
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
944
6
      << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
945
6
}
946
947
static bool checkExtensionProperty(Parser &P, SourceLocation Loc,
948
                                   OMPTraitProperty &TIProperty,
949
                                   OMPTraitSelector &TISelector,
950
175
                                   llvm::StringMap<SourceLocation> &Seen) {
951
175
  assert(TISelector.Kind ==
952
175
             llvm::omp::TraitSelector::implementation_extension &&
953
175
         "Only for extension properties, e.g., "
954
175
         "`implementation={extension(PROPERTY)}`");
955
175
  if (TIProperty.Kind == TraitProperty::invalid)
956
4
    return false;
957
958
171
  if (TIProperty.Kind ==
959
171
      TraitProperty::implementation_extension_disable_implicit_base)
960
14
    return true;
961
962
157
  if (TIProperty.Kind ==
963
157
      TraitProperty::implementation_extension_allow_templates)
964
15
    return true;
965
966
142
  if (TIProperty.Kind ==
967
142
      TraitProperty::implementation_extension_bind_to_declaration)
968
1
    return true;
969
970
145
  
auto IsMatchExtension = [](OMPTraitProperty &TP) 141
{
971
145
    return (TP.Kind ==
972
145
                llvm::omp::TraitProperty::implementation_extension_match_all ||
973
145
            TP.Kind ==
974
119
                llvm::omp::TraitProperty::implementation_extension_match_any ||
975
145
            TP.Kind ==
976
38
                llvm::omp::TraitProperty::implementation_extension_match_none);
977
145
  };
978
979
141
  if (IsMatchExtension(TIProperty)) {
980
141
    for (OMPTraitProperty &SeenProp : TISelector.Properties)
981
4
      if (IsMatchExtension(SeenProp)) {
982
4
        P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
983
4
        StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
984
4
            SeenProp.Kind, SeenProp.RawString);
985
4
        SourceLocation SeenLoc = Seen[SeenName];
986
4
        P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
987
4
            << CONTEXT_TRAIT_LVL << SeenName;
988
4
        return false;
989
4
      }
990
137
    return true;
991
141
  }
992
993
0
  llvm_unreachable("Unknown extension property!");
994
0
}
995
996
void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
997
                                     llvm::omp::TraitSet Set,
998
3.41k
                                     llvm::StringMap<SourceLocation> &Seen) {
999
3.41k
  assert(TISelector.Kind != TraitSelector::user_condition &&
1000
3.41k
         "User conditions are special properties not handled here!");
1001
1002
0
  SourceLocation PropertyLoc = Tok.getLocation();
1003
3.41k
  OMPTraitProperty TIProperty;
1004
3.41k
  parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
1005
1006
3.41k
  if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
1007
175
    if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
1008
175
                                TISelector, Seen))
1009
8
      TIProperty.Kind = TraitProperty::invalid;
1010
1011
  // If we have an invalid property here we already issued a warning.
1012
3.41k
  if (TIProperty.Kind == TraitProperty::invalid) {
1013
84
    if (PropertyLoc != Tok.getLocation())
1014
24
      Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1015
24
          << CONTEXT_TRAIT_LVL;
1016
84
    return;
1017
84
  }
1018
1019
3.33k
  if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
1020
3.33k
                                                 TISelector.Kind, Set)) {
1021
1022
    // If we make it here the property, selector, set, score, condition, ... are
1023
    // all valid (or have been corrected). Thus we can record the property.
1024
3.33k
    TISelector.Properties.push_back(TIProperty);
1025
3.33k
    return;
1026
3.33k
  }
1027
1028
0
  Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1029
0
      << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1030
0
                                           TIProperty.RawString)
1031
0
      << getOpenMPContextTraitSelectorName(TISelector.Kind)
1032
0
      << getOpenMPContextTraitSetName(Set);
1033
0
  Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1034
0
      << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1035
0
                                           TIProperty.RawString)
1036
0
      << getOpenMPContextTraitSelectorName(
1037
0
             getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1038
0
      << getOpenMPContextTraitSetName(
1039
0
             getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1040
0
  Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1041
0
      << CONTEXT_TRAIT_LVL;
1042
0
}
1043
1044
void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1045
                                       llvm::omp::TraitSet Set,
1046
2.96k
                                       llvm::StringMap<SourceLocation> &Seen) {
1047
2.96k
  TISelector.Kind = TraitSelector::invalid;
1048
1049
2.96k
  SourceLocation NameLoc = Tok.getLocation();
1050
2.96k
  StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL);
1051
2.96k
  if (Name.empty()) {
1052
50
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1053
50
        << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1054
50
    return;
1055
50
  }
1056
1057
2.91k
  TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1058
2.91k
  if (TISelector.Kind != TraitSelector::invalid) {
1059
2.86k
    if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1060
16
      TISelector.Kind = TraitSelector::invalid;
1061
2.86k
    return;
1062
2.86k
  }
1063
1064
  // It follows diagnosis and helping notes.
1065
48
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1066
48
      << Name << getOpenMPContextTraitSetName(Set);
1067
1068
48
  TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1069
48
  if (SetForName != TraitSet::invalid) {
1070
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1071
0
        << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1072
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1073
0
        << Name << "<selector-name>"
1074
0
        << "<property-name>";
1075
0
    return;
1076
0
  }
1077
48
  for (const auto &PotentialSet :
1078
48
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1079
192
        TraitSet::device}) {
1080
192
    TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1081
192
        PotentialSet, TraitSelector::invalid, Name);
1082
192
    if (PropertyForName == TraitProperty::invalid)
1083
192
      continue;
1084
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1085
0
        << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1086
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1087
0
        << getOpenMPContextTraitSetName(
1088
0
               getOpenMPContextTraitSetForProperty(PropertyForName))
1089
0
        << getOpenMPContextTraitSelectorName(
1090
0
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
1091
0
        << ("(" + Name + ")").str();
1092
0
    return;
1093
192
  }
1094
48
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1095
48
      << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1096
48
}
1097
1098
/// Parse optional 'score' '(' <expr> ')' ':'.
1099
2.35k
static ExprResult parseContextScore(Parser &P) {
1100
2.35k
  ExprResult ScoreExpr;
1101
2.35k
  llvm::SmallString<16> Buffer;
1102
2.35k
  StringRef SelectorName =
1103
2.35k
      P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1104
2.35k
  if (!SelectorName.equals("score"))
1105
2.08k
    return ScoreExpr;
1106
268
  (void)P.ConsumeToken();
1107
268
  SourceLocation RLoc;
1108
268
  ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1109
  // Parse ':'
1110
268
  if (P.getCurToken().is(tok::colon))
1111
204
    (void)P.ConsumeAnyToken();
1112
64
  else
1113
64
    P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1114
64
        << "':'"
1115
64
        << "score expression";
1116
268
  return ScoreExpr;
1117
2.35k
}
1118
1119
/// Parses an OpenMP context selector.
1120
///
1121
/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1122
void Parser::parseOMPContextSelector(
1123
    OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1124
2.96k
    llvm::StringMap<SourceLocation> &SeenSelectors) {
1125
2.96k
  unsigned short OuterPC = ParenCount;
1126
1127
  // If anything went wrong we issue an error or warning and then skip the rest
1128
  // of the selector. However, commas are ambiguous so we look for the nesting
1129
  // of parentheses here as well.
1130
2.96k
  auto FinishSelector = [OuterPC, this]() -> void {
1131
158
    bool Done = false;
1132
158
    while (!Done) {
1133
158
      while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1134
158
                         tok::annot_pragma_openmp_end},
1135
158
                        StopBeforeMatch))
1136
0
        ;
1137
158
      if (Tok.is(tok::r_paren) && 
OuterPC > ParenCount14
)
1138
0
        (void)ConsumeParen();
1139
158
      if (OuterPC <= ParenCount) {
1140
158
        Done = true;
1141
158
        break;
1142
158
      }
1143
0
      if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1144
0
        Done = true;
1145
0
        break;
1146
0
      }
1147
0
      (void)ConsumeAnyToken();
1148
0
    }
1149
158
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1150
158
        << CONTEXT_SELECTOR_LVL;
1151
158
  };
1152
1153
2.96k
  SourceLocation SelectorLoc = Tok.getLocation();
1154
2.96k
  parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1155
2.96k
  if (TISelector.Kind == TraitSelector::invalid)
1156
114
    return FinishSelector();
1157
1158
2.85k
  bool AllowsTraitScore = false;
1159
2.85k
  bool RequiresProperty = false;
1160
2.85k
  if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1161
2.85k
                                       RequiresProperty)) {
1162
16
    Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1163
16
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1164
16
        << getOpenMPContextTraitSetName(Set);
1165
16
    Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1166
16
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1167
16
        << getOpenMPContextTraitSetName(
1168
16
               getOpenMPContextTraitSetForSelector(TISelector.Kind))
1169
16
        << RequiresProperty;
1170
16
    return FinishSelector();
1171
16
  }
1172
1173
2.83k
  if (!RequiresProperty) {
1174
396
    TISelector.Properties.push_back(
1175
396
        {getOpenMPContextTraitPropertyForSelector(TISelector.Kind),
1176
396
         getOpenMPContextTraitSelectorName(TISelector.Kind)});
1177
396
    return;
1178
396
  }
1179
1180
2.43k
  if (!Tok.is(tok::l_paren)) {
1181
14
    Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1182
14
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1183
14
        << getOpenMPContextTraitSetName(Set);
1184
14
    return FinishSelector();
1185
14
  }
1186
1187
2.42k
  if (TISelector.Kind == TraitSelector::user_condition) {
1188
73
    SourceLocation RLoc;
1189
73
    ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1190
73
    if (!Condition.isUsable())
1191
14
      return FinishSelector();
1192
59
    TISelector.ScoreOrCondition = Condition.get();
1193
59
    TISelector.Properties.push_back(
1194
59
        {TraitProperty::user_condition_unknown, "<condition>"});
1195
59
    return;
1196
73
  }
1197
1198
2.35k
  BalancedDelimiterTracker BDT(*this, tok::l_paren,
1199
2.35k
                               tok::annot_pragma_openmp_end);
1200
  // Parse '('.
1201
2.35k
  (void)BDT.consumeOpen();
1202
1203
2.35k
  SourceLocation ScoreLoc = Tok.getLocation();
1204
2.35k
  ExprResult Score = parseContextScore(*this);
1205
1206
2.35k
  if (!AllowsTraitScore && 
!Score.isUnset()1.67k
) {
1207
64
    if (Score.isUsable()) {
1208
54
      Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1209
54
          << getOpenMPContextTraitSelectorName(TISelector.Kind)
1210
54
          << getOpenMPContextTraitSetName(Set) << Score.get();
1211
54
    } else {
1212
10
      Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1213
10
          << getOpenMPContextTraitSelectorName(TISelector.Kind)
1214
10
          << getOpenMPContextTraitSetName(Set) << "<invalid>";
1215
10
    }
1216
64
    Score = ExprResult();
1217
64
  }
1218
1219
2.35k
  if (Score.isUsable())
1220
186
    TISelector.ScoreOrCondition = Score.get();
1221
1222
2.35k
  llvm::StringMap<SourceLocation> SeenProperties;
1223
3.41k
  do {
1224
3.41k
    parseOMPContextProperty(TISelector, Set, SeenProperties);
1225
3.41k
  } while (TryConsumeToken(tok::comma));
1226
1227
  // Parse ')'.
1228
2.35k
  BDT.consumeClose();
1229
2.35k
}
1230
1231
void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1232
2.94k
                                  llvm::StringMap<SourceLocation> &Seen) {
1233
2.94k
  TISet.Kind = TraitSet::invalid;
1234
1235
2.94k
  SourceLocation NameLoc = Tok.getLocation();
1236
2.94k
  StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL);
1237
2.94k
  if (Name.empty()) {
1238
18
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1239
18
        << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1240
18
    return;
1241
18
  }
1242
1243
2.92k
  TISet.Kind = getOpenMPContextTraitSetKind(Name);
1244
2.92k
  if (TISet.Kind != TraitSet::invalid) {
1245
2.81k
    if (checkForDuplicates(*this, Name, NameLoc, Seen,
1246
2.81k
                           CONTEXT_SELECTOR_SET_LVL))
1247
0
      TISet.Kind = TraitSet::invalid;
1248
2.81k
    return;
1249
2.81k
  }
1250
1251
  // It follows diagnosis and helping notes.
1252
110
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1253
1254
110
  TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1255
110
  if (SelectorForName != TraitSelector::invalid) {
1256
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1257
0
        << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1258
0
    bool AllowsTraitScore = false;
1259
0
    bool RequiresProperty = false;
1260
0
    isValidTraitSelectorForTraitSet(
1261
0
        SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1262
0
        AllowsTraitScore, RequiresProperty);
1263
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1264
0
        << getOpenMPContextTraitSetName(
1265
0
               getOpenMPContextTraitSetForSelector(SelectorForName))
1266
0
        << Name << (RequiresProperty ? "(<property-name>)" : "");
1267
0
    return;
1268
0
  }
1269
110
  for (const auto &PotentialSet :
1270
110
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1271
440
        TraitSet::device}) {
1272
440
    TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1273
440
        PotentialSet, TraitSelector::invalid, Name);
1274
440
    if (PropertyForName == TraitProperty::invalid)
1275
440
      continue;
1276
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1277
0
        << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1278
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1279
0
        << getOpenMPContextTraitSetName(
1280
0
               getOpenMPContextTraitSetForProperty(PropertyForName))
1281
0
        << getOpenMPContextTraitSelectorName(
1282
0
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
1283
0
        << ("(" + Name + ")").str();
1284
0
    return;
1285
440
  }
1286
110
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1287
110
      << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1288
110
}
1289
1290
/// Parses an OpenMP context selector set.
1291
///
1292
/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1293
void Parser::parseOMPContextSelectorSet(
1294
2.94k
    OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1295
2.94k
  auto OuterBC = BraceCount;
1296
1297
  // If anything went wrong we issue an error or warning and then skip the rest
1298
  // of the set. However, commas are ambiguous so we look for the nesting
1299
  // of braces here as well.
1300
2.94k
  auto FinishSelectorSet = [this, OuterBC]() -> void {
1301
128
    bool Done = false;
1302
128
    while (!Done) {
1303
128
      while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1304
128
                         tok::annot_pragma_openmp_end},
1305
128
                        StopBeforeMatch))
1306
0
        ;
1307
128
      if (Tok.is(tok::r_brace) && 
OuterBC > BraceCount4
)
1308
0
        (void)ConsumeBrace();
1309
128
      if (OuterBC <= BraceCount) {
1310
128
        Done = true;
1311
128
        break;
1312
128
      }
1313
0
      if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1314
0
        Done = true;
1315
0
        break;
1316
0
      }
1317
0
      (void)ConsumeAnyToken();
1318
0
    }
1319
128
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1320
128
        << CONTEXT_SELECTOR_SET_LVL;
1321
128
  };
1322
1323
2.94k
  parseOMPTraitSetKind(TISet, SeenSets);
1324
2.94k
  if (TISet.Kind == TraitSet::invalid)
1325
128
    return FinishSelectorSet();
1326
1327
  // Parse '='.
1328
2.81k
  if (!TryConsumeToken(tok::equal))
1329
10
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1330
10
        << "="
1331
10
        << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1332
10
            "\"")
1333
10
               .str();
1334
1335
  // Parse '{'.
1336
2.81k
  if (Tok.is(tok::l_brace)) {
1337
2.80k
    (void)ConsumeBrace();
1338
2.80k
  } else {
1339
12
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1340
12
        << "{"
1341
12
        << ("'=' that follows the context set name \"" +
1342
12
            getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1343
12
               .str();
1344
12
  }
1345
1346
2.81k
  llvm::StringMap<SourceLocation> SeenSelectors;
1347
2.96k
  do {
1348
2.96k
    OMPTraitSelector TISelector;
1349
2.96k
    parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1350
2.96k
    if (TISelector.Kind != TraitSelector::invalid &&
1351
2.96k
        
!TISelector.Properties.empty()2.85k
)
1352
2.73k
      TISet.Selectors.push_back(TISelector);
1353
2.96k
  } while (TryConsumeToken(tok::comma));
1354
1355
  // Parse '}'.
1356
2.81k
  if (Tok.is(tok::r_brace)) {
1357
2.79k
    (void)ConsumeBrace();
1358
2.79k
  } else {
1359
22
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1360
22
        << "}"
1361
22
        << ("context selectors for the context set \"" +
1362
22
            getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1363
22
               .str();
1364
22
  }
1365
2.81k
}
1366
1367
/// Parse OpenMP context selectors:
1368
///
1369
/// <trait-set-selector> [, <trait-set-selector>]*
1370
2.59k
bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
1371
2.59k
  llvm::StringMap<SourceLocation> SeenSets;
1372
2.94k
  do {
1373
2.94k
    OMPTraitSet TISet;
1374
2.94k
    parseOMPContextSelectorSet(TISet, SeenSets);
1375
2.94k
    if (TISet.Kind != TraitSet::invalid && 
!TISet.Selectors.empty()2.81k
)
1376
2.63k
      TI.Sets.push_back(TISet);
1377
2.94k
  } while (TryConsumeToken(tok::comma));
1378
1379
2.59k
  return false;
1380
2.59k
}
1381
1382
/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
1383
void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1384
                                           CachedTokens &Toks,
1385
2.12k
                                           SourceLocation Loc) {
1386
2.12k
  PP.EnterToken(Tok, /*IsReinject*/ true);
1387
2.12k
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1388
2.12k
                      /*IsReinject*/ true);
1389
  // Consume the previously pushed token.
1390
2.12k
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1391
2.12k
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1392
1393
2.12k
  FNContextRAII FnContext(*this, Ptr);
1394
  // Parse function declaration id.
1395
2.12k
  SourceLocation RLoc;
1396
  // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1397
  // instead of MemberExprs.
1398
2.12k
  ExprResult AssociatedFunction;
1399
2.12k
  {
1400
    // Do not mark function as is used to prevent its emission if this is the
1401
    // only place where it is used.
1402
2.12k
    EnterExpressionEvaluationContext Unevaluated(
1403
2.12k
        Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1404
2.12k
    AssociatedFunction = ParseOpenMPParensExpr(
1405
2.12k
        getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1406
2.12k
        /*IsAddressOfOperand=*/true);
1407
2.12k
  }
1408
2.12k
  if (!AssociatedFunction.isUsable()) {
1409
14
    if (!Tok.is(tok::annot_pragma_openmp_end))
1410
2
      while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1411
0
        ;
1412
    // Skip the last annot_pragma_openmp_end.
1413
14
    (void)ConsumeAnnotationToken();
1414
14
    return;
1415
14
  }
1416
1417
2.11k
  OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1418
2.11k
  ASTContext &ASTCtx = Actions.getASTContext();
1419
2.11k
  OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
1420
2.11k
  SmallVector<Expr *, 6> AdjustNothing;
1421
2.11k
  SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1422
2.11k
  SmallVector<OMPDeclareVariantAttr::InteropType, 3> AppendArgs;
1423
2.11k
  SourceLocation AdjustArgsLoc, AppendArgsLoc;
1424
1425
  // At least one clause is required.
1426
2.11k
  if (Tok.is(tok::annot_pragma_openmp_end)) {
1427
29
    Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1428
29
        << (getLangOpts().OpenMP < 51 ? 
026
:
13
);
1429
29
  }
1430
1431
2.11k
  bool IsError = false;
1432
4.32k
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1433
2.25k
    OpenMPClauseKind CKind = Tok.isAnnotation()
1434
2.25k
                                 ? 
OMPC_unknown0
1435
2.25k
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
1436
2.25k
    if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1437
2.25k
                                     getLangOpts().OpenMP)) {
1438
25
      Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1439
25
          << (getLangOpts().OpenMP < 51 ? 
022
:
13
);
1440
25
      IsError = true;
1441
25
    }
1442
2.25k
    if (!IsError) {
1443
2.22k
      switch (CKind) {
1444
2.07k
      case OMPC_match:
1445
2.07k
        IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1446
2.07k
        break;
1447
54
      case OMPC_adjust_args: {
1448
54
        AdjustArgsLoc = Tok.getLocation();
1449
54
        ConsumeToken();
1450
54
        Sema::OpenMPVarListDataTy Data;
1451
54
        SmallVector<Expr *> Vars;
1452
54
        IsError = ParseOpenMPVarList(OMPD_declare_variant, OMPC_adjust_args,
1453
54
                                     Vars, Data);
1454
54
        if (!IsError)
1455
51
          llvm::append_range(Data.ExtraModifier == OMPC_ADJUST_ARGS_nothing
1456
51
                                 ? 
AdjustNothing22
1457
51
                                 : 
AdjustNeedDevicePtr29
,
1458
51
                             Vars);
1459
54
        break;
1460
0
      }
1461
102
      case OMPC_append_args:
1462
102
        if (!AppendArgs.empty()) {
1463
3
          Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1464
3
              << getOpenMPDirectiveName(OMPD_declare_variant)
1465
3
              << getOpenMPClauseName(CKind) << 0;
1466
3
          IsError = true;
1467
3
        }
1468
102
        if (!IsError) {
1469
99
          AppendArgsLoc = Tok.getLocation();
1470
99
          ConsumeToken();
1471
99
          IsError = parseOpenMPAppendArgs(AppendArgs);
1472
99
        }
1473
102
        break;
1474
0
      default:
1475
0
        llvm_unreachable("Unexpected clause for declare variant.");
1476
2.22k
      }
1477
2.22k
    }
1478
2.25k
    if (IsError) {
1479
54
      while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1480
8
        ;
1481
      // Skip the last annot_pragma_openmp_end.
1482
46
      (void)ConsumeAnnotationToken();
1483
46
      return;
1484
46
    }
1485
    // Skip ',' if any.
1486
2.20k
    if (Tok.is(tok::comma))
1487
8
      ConsumeToken();
1488
2.20k
  }
1489
1490
2.06k
  Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1491
2.06k
      Actions.checkOpenMPDeclareVariantFunction(
1492
2.06k
          Ptr, AssociatedFunction.get(), TI, AppendArgs.size(),
1493
2.06k
          SourceRange(Loc, Tok.getLocation()));
1494
1495
2.06k
  if (DeclVarData && 
!TI.Sets.empty()1.94k
)
1496
1.71k
    Actions.ActOnOpenMPDeclareVariantDirective(
1497
1.71k
        DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1498
1.71k
        AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1499
1.71k
        SourceRange(Loc, Tok.getLocation()));
1500
1501
  // Skip the last annot_pragma_openmp_end.
1502
2.06k
  (void)ConsumeAnnotationToken();
1503
2.06k
}
1504
1505
/// Parse a list of interop-types. These are 'target' and 'targetsync'. Both
1506
/// are allowed but duplication of either is not meaningful.
1507
static Optional<OMPDeclareVariantAttr::InteropType>
1508
202
parseInteropTypeList(Parser &P) {
1509
202
  const Token &Tok = P.getCurToken();
1510
202
  bool HasError = false;
1511
202
  bool IsTarget = false;
1512
202
  bool IsTargetSync = false;
1513
1514
216
  while (Tok.is(tok::identifier)) {
1515
213
    if (Tok.getIdentifierInfo()->isStr("target")) {
1516
      // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
1517
      // Each interop-type may be specified on an action-clause at most
1518
      // once.
1519
143
      if (IsTarget)
1520
4
        P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
1521
143
      IsTarget = true;
1522
143
    } else 
if (70
Tok.getIdentifierInfo()->isStr("targetsync")70
) {
1523
65
      if (IsTargetSync)
1524
3
        P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
1525
65
      IsTargetSync = true;
1526
65
    } else {
1527
5
      HasError = true;
1528
5
      P.Diag(Tok, diag::err_omp_expected_interop_type);
1529
5
    }
1530
213
    P.ConsumeToken();
1531
1532
213
    if (!Tok.is(tok::comma))
1533
199
      break;
1534
14
    P.ConsumeToken();
1535
14
  }
1536
202
  if (HasError)
1537
5
    return None;
1538
1539
197
  if (!IsTarget && 
!IsTargetSync59
) {
1540
3
    P.Diag(Tok, diag::err_omp_expected_interop_type);
1541
3
    return None;
1542
3
  }
1543
1544
  // As of OpenMP 5.1,there are two interop-types, "target" and
1545
  // "targetsync". Either or both are allowed for a single interop.
1546
194
  if (IsTarget && 
IsTargetSync138
)
1547
6
    return OMPDeclareVariantAttr::Target_TargetSync;
1548
188
  if (IsTarget)
1549
132
    return OMPDeclareVariantAttr::Target;
1550
56
  return OMPDeclareVariantAttr::TargetSync;
1551
188
}
1552
1553
bool Parser::parseOpenMPAppendArgs(
1554
99
    SmallVectorImpl<OMPDeclareVariantAttr::InteropType> &InterOpTypes) {
1555
99
  bool HasError = false;
1556
  // Parse '('.
1557
99
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1558
99
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1559
99
                         getOpenMPClauseName(OMPC_append_args).data()))
1560
0
    return true;
1561
1562
  // Parse the list of append-ops, each is;
1563
  // interop(interop-type[,interop-type]...)
1564
214
  
while (99
Tok.is(tok::identifier) &&
Tok.getIdentifierInfo()->isStr("interop")118
) {
1565
115
    ConsumeToken();
1566
115
    BalancedDelimiterTracker IT(*this, tok::l_paren,
1567
115
                                tok::annot_pragma_openmp_end);
1568
115
    if (IT.expectAndConsume(diag::err_expected_lparen_after, "interop"))
1569
0
      return true;
1570
1571
    // Parse the interop-types.
1572
115
    if (Optional<OMPDeclareVariantAttr::InteropType> IType =
1573
115
            parseInteropTypeList(*this))
1574
109
      InterOpTypes.push_back(*IType);
1575
6
    else
1576
6
      HasError = true;
1577
1578
115
    IT.consumeClose();
1579
115
    if (Tok.is(tok::comma))
1580
19
      ConsumeToken();
1581
115
  }
1582
99
  if (!HasError && 
InterOpTypes.empty()93
) {
1583
3
    HasError = true;
1584
3
    Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1585
3
    SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1586
3
              StopBeforeMatch);
1587
3
  }
1588
99
  HasError = T.consumeClose() || HasError;
1589
99
  return HasError;
1590
99
}
1591
1592
bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1593
                                               OMPTraitInfo &TI,
1594
2.38k
                                               OMPTraitInfo *ParentTI) {
1595
  // Parse 'match'.
1596
2.38k
  OpenMPClauseKind CKind = Tok.isAnnotation()
1597
2.38k
                               ? 
OMPC_unknown4
1598
2.38k
                               : 
getOpenMPClauseKind(PP.getSpelling(Tok))2.38k
;
1599
2.38k
  if (CKind != OMPC_match) {
1600
6
    Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1601
6
        << (getLangOpts().OpenMP < 51 ? 0 : 
10
);
1602
6
    return true;
1603
6
  }
1604
2.37k
  (void)ConsumeToken();
1605
  // Parse '('.
1606
2.37k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1607
2.37k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1608
2.37k
                         getOpenMPClauseName(OMPC_match).data()))
1609
8
    return true;
1610
1611
  // Parse inner context selectors.
1612
2.37k
  parseOMPContextSelectors(Loc, TI);
1613
1614
  // Parse ')'
1615
2.37k
  (void)T.consumeClose();
1616
1617
2.37k
  if (!ParentTI)
1618
2.33k
    return false;
1619
1620
  // Merge the parent/outer trait info into the one we just parsed and diagnose
1621
  // problems.
1622
  // TODO: Keep some source location in the TI to provide better diagnostics.
1623
  // TODO: Perform some kind of equivalence check on the condition and score
1624
  //       expressions.
1625
60
  
for (const OMPTraitSet &ParentSet : ParentTI->Sets)38
{
1626
60
    bool MergedSet = false;
1627
80
    for (OMPTraitSet &Set : TI.Sets) {
1628
80
      if (Set.Kind != ParentSet.Kind)
1629
44
        continue;
1630
36
      MergedSet = true;
1631
38
      for (const OMPTraitSelector &ParentSelector : ParentSet.Selectors) {
1632
38
        bool MergedSelector = false;
1633
42
        for (OMPTraitSelector &Selector : Set.Selectors) {
1634
42
          if (Selector.Kind != ParentSelector.Kind)
1635
18
            continue;
1636
24
          MergedSelector = true;
1637
24
          for (const OMPTraitProperty &ParentProperty :
1638
28
               ParentSelector.Properties) {
1639
28
            bool MergedProperty = false;
1640
34
            for (OMPTraitProperty &Property : Selector.Properties) {
1641
              // Ignore "equivalent" properties.
1642
34
              if (Property.Kind != ParentProperty.Kind)
1643
22
                continue;
1644
1645
              // If the kind is the same but the raw string not, we don't want
1646
              // to skip out on the property.
1647
12
              MergedProperty |= Property.RawString == ParentProperty.RawString;
1648
1649
12
              if (Property.RawString == ParentProperty.RawString &&
1650
12
                  
Selector.ScoreOrCondition == ParentSelector.ScoreOrCondition10
)
1651
6
                continue;
1652
1653
6
              if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1654
2
                Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1655
4
              } else if (Selector.ScoreOrCondition !=
1656
4
                         ParentSelector.ScoreOrCondition) {
1657
2
                Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1658
2
                    << getOpenMPContextTraitPropertyName(
1659
2
                           ParentProperty.Kind, ParentProperty.RawString)
1660
2
                    << getOpenMPContextTraitSelectorName(ParentSelector.Kind)
1661
2
                    << getOpenMPContextTraitSetName(ParentSet.Kind);
1662
2
              }
1663
6
            }
1664
28
            if (!MergedProperty)
1665
18
              Selector.Properties.push_back(ParentProperty);
1666
28
          }
1667
24
        }
1668
38
        if (!MergedSelector)
1669
14
          Set.Selectors.push_back(ParentSelector);
1670
38
      }
1671
36
    }
1672
60
    if (!MergedSet)
1673
24
      TI.Sets.push_back(ParentSet);
1674
60
  }
1675
1676
38
  return false;
1677
2.37k
}
1678
1679
/// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
1680
/// where
1681
///
1682
///   clause:
1683
///     'ext_IMPL_DEFINED'
1684
///     'absent' '(' directive-name [, directive-name]* ')'
1685
///     'contains' '(' directive-name [, directive-name]* ')'
1686
///     'holds' '(' scalar-expression ')'
1687
///     'no_openmp'
1688
///     'no_openmp_routines'
1689
///     'no_parallelism'
1690
///
1691
void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
1692
205
                                         SourceLocation Loc) {
1693
205
  SmallVector<std::string, 4> Assumptions;
1694
205
  bool SkippedClauses = false;
1695
1696
205
  auto SkipBraces = [&](llvm::StringRef Spelling, bool IssueNote) {
1697
82
    BalancedDelimiterTracker T(*this, tok::l_paren,
1698
82
                               tok::annot_pragma_openmp_end);
1699
82
    if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1700
0
      return;
1701
82
    T.skipToEnd();
1702
82
    if (IssueNote && 
T.getCloseLocation().isValid()58
)
1703
52
      Diag(T.getCloseLocation(),
1704
52
           diag::note_omp_assumption_clause_continue_here);
1705
82
  };
1706
1707
  /// Helper to determine which AssumptionClauseMapping (ACM) in the
1708
  /// AssumptionClauseMappings table matches \p RawString. The return value is
1709
  /// the index of the matching ACM into the table or -1 if there was no match.
1710
295
  auto MatchACMClause = [&](StringRef RawString) {
1711
295
    llvm::StringSwitch<int> SS(RawString);
1712
295
    unsigned ACMIdx = 0;
1713
2.06k
    for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1714
2.06k
      if (ACMI.StartsWith)
1715
295
        SS.StartsWith(ACMI.Identifier, ACMIdx++);
1716
1.77k
      else
1717
1.77k
        SS.Case(ACMI.Identifier, ACMIdx++);
1718
2.06k
    }
1719
295
    return SS.Default(-1);
1720
295
  };
1721
1722
510
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1723
305
    IdentifierInfo *II = nullptr;
1724
305
    SourceLocation StartLoc = Tok.getLocation();
1725
305
    int Idx = -1;
1726
305
    if (Tok.isAnyIdentifier()) {
1727
295
      II = Tok.getIdentifierInfo();
1728
295
      Idx = MatchACMClause(II->getName());
1729
295
    }
1730
305
    ConsumeAnyToken();
1731
1732
305
    bool NextIsLPar = Tok.is(tok::l_paren);
1733
    // Handle unknown clauses by skipping them.
1734
305
    if (Idx == -1) {
1735
110
      Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1736
110
          << llvm::omp::getOpenMPDirectiveName(DKind)
1737
110
          << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1738
110
      if (NextIsLPar)
1739
36
        SkipBraces(II ? II->getName() : 
""0
, /* IssueNote */ true);
1740
110
      SkippedClauses = true;
1741
110
      continue;
1742
110
    }
1743
195
    const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1744
195
    if (ACMI.HasDirectiveList || 
ACMI.HasExpression179
) {
1745
      // TODO: We ignore absent, contains, and holds assumptions for now. We
1746
      //       also do not verify the content in the parenthesis at all.
1747
24
      SkippedClauses = true;
1748
24
      SkipBraces(II->getName(), /* IssueNote */ false);
1749
24
      continue;
1750
24
    }
1751
1752
171
    if (NextIsLPar) {
1753
22
      Diag(Tok.getLocation(),
1754
22
           diag::warn_omp_unknown_assumption_clause_without_args)
1755
22
          << II;
1756
22
      SkipBraces(II->getName(), /* IssueNote */ true);
1757
22
    }
1758
1759
171
    assert(II && "Expected an identifier clause!");
1760
0
    std::string Assumption = II->getName().str();
1761
171
    if (ACMI.StartsWith)
1762
89
      Assumption = "ompx_" + Assumption.substr(ACMI.Identifier.size());
1763
82
    else
1764
82
      Assumption = "omp_" + Assumption;
1765
171
    Assumptions.push_back(Assumption);
1766
171
  }
1767
1768
205
  Actions.ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions, SkippedClauses);
1769
205
}
1770
1771
122
void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
1772
122
  if (Actions.isInOpenMPAssumeScope())
1773
118
    Actions.ActOnOpenMPEndAssumesDirective();
1774
4
  else
1775
4
    Diag(Loc, diag::err_expected_begin_assumes);
1776
122
}
1777
1778
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1779
///
1780
///    default-clause:
1781
///         'default' '(' 'none' | 'shared'  | 'private' | 'firstprivate' ')
1782
///
1783
///    proc_bind-clause:
1784
///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1785
///
1786
///    device_type-clause:
1787
///         'device_type' '(' 'host' | 'nohost' | 'any' )'
1788
namespace {
1789
struct SimpleClauseData {
1790
  unsigned Type;
1791
  SourceLocation Loc;
1792
  SourceLocation LOpen;
1793
  SourceLocation TypeLoc;
1794
  SourceLocation RLoc;
1795
  SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1796
                   SourceLocation TypeLoc, SourceLocation RLoc)
1797
3.52k
      : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1798
};
1799
} // anonymous namespace
1800
1801
static Optional<SimpleClauseData>
1802
3.74k
parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1803
3.74k
  const Token &Tok = P.getCurToken();
1804
3.74k
  SourceLocation Loc = Tok.getLocation();
1805
3.74k
  SourceLocation LOpen = P.ConsumeToken();
1806
  // Parse '('.
1807
3.74k
  BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1808
3.74k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1809
3.74k
                         getOpenMPClauseName(Kind).data()))
1810
218
    return llvm::None;
1811
1812
3.52k
  unsigned Type = getOpenMPSimpleClauseType(
1813
3.52k
      Kind, Tok.isAnnotation() ? 
""218
:
P.getPreprocessor().getSpelling(Tok)3.30k
,
1814
3.52k
      P.getLangOpts());
1815
3.52k
  SourceLocation TypeLoc = Tok.getLocation();
1816
3.52k
  if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)3.38k
&&
1817
3.52k
      
Tok.isNot(tok::annot_pragma_openmp_end)3.38k
)
1818
3.16k
    P.ConsumeAnyToken();
1819
1820
  // Parse ')'.
1821
3.52k
  SourceLocation RLoc = Tok.getLocation();
1822
3.52k
  if (!T.consumeClose())
1823
3.01k
    RLoc = T.getCloseLocation();
1824
1825
3.52k
  return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1826
3.74k
}
1827
1828
void Parser::ParseOMPDeclareTargetClauses(
1829
537
    Sema::DeclareTargetContextInfo &DTCI) {
1830
537
  SourceLocation DeviceTypeLoc;
1831
537
  bool RequiresToOrLinkOrIndirectClause = false;
1832
537
  bool HasToOrLinkOrIndirectClause = false;
1833
1.25k
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1834
793
    OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1835
793
    bool HasIdentifier = Tok.is(tok::identifier);
1836
793
    if (HasIdentifier) {
1837
      // If we see any clause we need a to or link clause.
1838
691
      RequiresToOrLinkOrIndirectClause = true;
1839
691
      IdentifierInfo *II = Tok.getIdentifierInfo();
1840
691
      StringRef ClauseName = II->getName();
1841
691
      bool IsDeviceTypeClause =
1842
691
          getLangOpts().OpenMP >= 50 &&
1843
691
          
getOpenMPClauseKind(ClauseName) == OMPC_device_type622
;
1844
1845
691
      bool IsIndirectClause = getLangOpts().OpenMP >= 51 &&
1846
691
                              
getOpenMPClauseKind(ClauseName) == OMPC_indirect221
;
1847
691
      if (DTCI.Indirect && 
IsIndirectClause6
) {
1848
3
        Diag(Tok, diag::err_omp_more_one_clause)
1849
3
            << getOpenMPDirectiveName(OMPD_declare_target)
1850
3
            << getOpenMPClauseName(OMPC_indirect) << 0;
1851
3
        break;
1852
3
      }
1853
688
      bool IsToOrLinkClause =
1854
688
          OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1855
688
      assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!");
1856
1857
688
      if (!IsDeviceTypeClause && 
!IsIndirectClause506
&&
1858
688
          
DTCI.Kind == OMPD_begin_declare_target484
) {
1859
6
        Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1860
6
            << ClauseName << (getLangOpts().OpenMP >= 51 ? 3 : 
00
);
1861
6
        break;
1862
6
      }
1863
682
      if (!IsDeviceTypeClause && 
!IsToOrLinkClause500
&&
!IsIndirectClause67
) {
1864
45
        Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1865
45
            << ClauseName
1866
45
            << (getLangOpts().OpenMP >= 51   ? 
413
1867
45
                : 
getLangOpts().OpenMP >= 5032
?
210
1868
32
                                             : 
122
);
1869
45
        break;
1870
45
      }
1871
1872
637
      if (IsToOrLinkClause || 
IsIndirectClause204
)
1873
455
        HasToOrLinkOrIndirectClause = true;
1874
1875
637
      if (IsIndirectClause) {
1876
22
        if (!ParseOpenMPIndirectClause(DTCI, /*ParseOnly*/ false))
1877
3
          break;
1878
19
        continue;
1879
22
      }
1880
      // Parse 'device_type' clause and go to next clause if any.
1881
615
      if (IsDeviceTypeClause) {
1882
182
        Optional<SimpleClauseData> DevTypeData =
1883
182
            parseOpenMPSimpleClause(*this, OMPC_device_type);
1884
182
        if (DevTypeData) {
1885
182
          if (DeviceTypeLoc.isValid()) {
1886
            // We already saw another device_type clause, diagnose it.
1887
10
            Diag(DevTypeData.value().Loc,
1888
10
                 diag::warn_omp_more_one_device_type_clause);
1889
10
            break;
1890
10
          }
1891
172
          switch (static_cast<OpenMPDeviceType>(DevTypeData.value().Type)) {
1892
24
          case OMPC_DEVICE_TYPE_any:
1893
24
            DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1894
24
            break;
1895
64
          case OMPC_DEVICE_TYPE_host:
1896
64
            DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1897
64
            break;
1898
84
          case OMPC_DEVICE_TYPE_nohost:
1899
84
            DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1900
84
            break;
1901
0
          case OMPC_DEVICE_TYPE_unknown:
1902
0
            llvm_unreachable("Unexpected device_type");
1903
172
          }
1904
172
          DeviceTypeLoc = DevTypeData->Loc;
1905
172
        }
1906
172
        continue;
1907
182
      }
1908
433
      ConsumeToken();
1909
433
    }
1910
1911
535
    if (DTCI.Kind == OMPD_declare_target || 
HasIdentifier0
) {
1912
535
      auto &&Callback = [this, MT, &DTCI](CXXScopeSpec &SS,
1913
626
                                          DeclarationNameInfo NameInfo) {
1914
626
        NamedDecl *ND =
1915
626
            Actions.lookupOpenMPDeclareTargetName(getCurScope(), SS, NameInfo);
1916
626
        if (!ND)
1917
36
          return;
1918
590
        Sema::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.getLoc()};
1919
590
        bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1920
590
        if (!FirstMapping)
1921
24
          Diag(NameInfo.getLoc(), diag::err_omp_declare_target_multiple)
1922
24
              << NameInfo.getName();
1923
590
      };
1924
535
      if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1925
535
                                   /*AllowScopeSpecifier=*/true))
1926
12
        break;
1927
535
    }
1928
1929
523
    if (Tok.is(tok::l_paren)) {
1930
0
      Diag(Tok,
1931
0
           diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1932
0
      break;
1933
0
    }
1934
523
    if (!HasIdentifier && 
Tok.isNot(tok::annot_pragma_openmp_end)90
) {
1935
0
      Diag(Tok,
1936
0
           diag::err_omp_declare_target_unexpected_clause_after_implicit_to);
1937
0
      break;
1938
0
    }
1939
1940
    // Consume optional ','.
1941
523
    if (Tok.is(tok::comma))
1942
16
      ConsumeToken();
1943
523
  }
1944
1945
537
  if (DTCI.Indirect && 
DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any19
)
1946
3
    Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1947
1948
  // For declare target require at least 'to' or 'link' to be present.
1949
537
  if (DTCI.Kind == OMPD_declare_target && 
RequiresToOrLinkOrIndirectClause508
&&
1950
537
      
!HasToOrLinkOrIndirectClause406
)
1951
15
    Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause)
1952
15
        << (getLangOpts().OpenMP >= 51 ? 
18
:
07
);
1953
1954
537
  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1955
537
}
1956
1957
9.13k
void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1958
  // The last seen token is annot_pragma_openmp_end - need to check for
1959
  // extra tokens.
1960
9.13k
  if (Tok.is(tok::annot_pragma_openmp_end))
1961
5.26k
    return;
1962
1963
3.87k
  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1964
3.87k
      << getOpenMPDirectiveName(DKind);
1965
9.06k
  while (Tok.isNot(tok::annot_pragma_openmp_end))
1966
5.19k
    ConsumeAnyToken();
1967
3.87k
}
1968
1969
void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1970
                                  OpenMPDirectiveKind ExpectedKind,
1971
                                  OpenMPDirectiveKind FoundKind,
1972
                                  SourceLocation BeginLoc,
1973
                                  SourceLocation FoundLoc,
1974
763
                                  bool SkipUntilOpenMPEnd) {
1975
763
  int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 
0705
:
158
;
1976
1977
763
  if (FoundKind == ExpectedKind) {
1978
757
    ConsumeAnyToken();
1979
757
    skipUntilPragmaOpenMPEnd(ExpectedKind);
1980
757
    return;
1981
757
  }
1982
1983
6
  Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1984
6
      << DiagSelection;
1985
6
  Diag(BeginLoc, diag::note_matching)
1986
6
      << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1987
6
  if (SkipUntilOpenMPEnd)
1988
6
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1989
6
}
1990
1991
void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
1992
                                               OpenMPDirectiveKind EndDKind,
1993
705
                                               SourceLocation DKLoc) {
1994
705
  parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1995
705
                       Tok.getLocation(),
1996
705
                       /* SkipUntilOpenMPEnd */ false);
1997
  // Skip the last annot_pragma_openmp_end.
1998
705
  if (Tok.is(tok::annot_pragma_openmp_end))
1999
705
    ConsumeAnnotationToken();
2000
705
}
2001
2002
/// Parsing of declarative OpenMP directives.
2003
///
2004
///       threadprivate-directive:
2005
///         annot_pragma_openmp 'threadprivate' simple-variable-list
2006
///         annot_pragma_openmp_end
2007
///
2008
///       allocate-directive:
2009
///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
2010
///         annot_pragma_openmp_end
2011
///
2012
///       declare-reduction-directive:
2013
///        annot_pragma_openmp 'declare' 'reduction' [...]
2014
///        annot_pragma_openmp_end
2015
///
2016
///       declare-mapper-directive:
2017
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2018
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2019
///         annot_pragma_openmp_end
2020
///
2021
///       declare-simd-directive:
2022
///         annot_pragma_openmp 'declare simd' {<clause> [,]}
2023
///         annot_pragma_openmp_end
2024
///         <function declaration/definition>
2025
///
2026
///       requires directive:
2027
///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
2028
///         annot_pragma_openmp_end
2029
///
2030
///       assumes directive:
2031
///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
2032
///         annot_pragma_openmp_end
2033
///       or
2034
///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
2035
///         annot_pragma_openmp 'end assumes'
2036
///         annot_pragma_openmp_end
2037
///
2038
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
2039
    AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed,
2040
10.0k
    DeclSpec::TST TagType, Decl *Tag) {
2041
10.0k
  assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2042
10.0k
         "Not an OpenMP directive!");
2043
0
  ParsingOpenMPDirectiveRAII DirScope(*this);
2044
10.0k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
2045
2046
10.0k
  SourceLocation Loc;
2047
10.0k
  OpenMPDirectiveKind DKind;
2048
10.0k
  if (Delayed) {
2049
778
    TentativeParsingAction TPA(*this);
2050
778
    Loc = ConsumeAnnotationToken();
2051
778
    DKind = parseOpenMPDirectiveKind(*this);
2052
778
    if (DKind == OMPD_declare_reduction || 
DKind == OMPD_declare_mapper718
) {
2053
      // Need to delay parsing until completion of the parent class.
2054
86
      TPA.Revert();
2055
86
      CachedTokens Toks;
2056
86
      unsigned Cnt = 1;
2057
86
      Toks.push_back(Tok);
2058
1.41k
      while (Cnt && 
Tok.isNot(tok::eof)1.33k
) {
2059
1.33k
        (void)ConsumeAnyToken();
2060
1.33k
        if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2061
0
          ++Cnt;
2062
1.33k
        else if (Tok.is(tok::annot_pragma_openmp_end))
2063
86
          --Cnt;
2064
1.33k
        Toks.push_back(Tok);
2065
1.33k
      }
2066
      // Skip last annot_pragma_openmp_end.
2067
86
      if (Cnt == 0)
2068
86
        (void)ConsumeAnyToken();
2069
86
      auto *LP = new LateParsedPragma(this, AS);
2070
86
      LP->takeToks(Toks);
2071
86
      getCurrentClass().LateParsedDeclarations.push_back(LP);
2072
86
      return nullptr;
2073
86
    }
2074
692
    TPA.Commit();
2075
9.22k
  } else {
2076
9.22k
    Loc = ConsumeAnnotationToken();
2077
9.22k
    DKind = parseOpenMPDirectiveKind(*this);
2078
9.22k
  }
2079
2080
9.91k
  switch (DKind) {
2081
2.57k
  case OMPD_threadprivate: {
2082
2.57k
    ConsumeToken();
2083
2.57k
    DeclDirectiveListParserHelper Helper(this, DKind);
2084
2.57k
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2085
2.57k
                                  /*AllowScopeSpecifier=*/true)) {
2086
2.53k
      skipUntilPragmaOpenMPEnd(DKind);
2087
      // Skip the last annot_pragma_openmp_end.
2088
2.53k
      ConsumeAnnotationToken();
2089
2.53k
      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
2090
2.53k
                                                       Helper.getIdentifiers());
2091
2.53k
    }
2092
40
    break;
2093
2.57k
  }
2094
440
  case OMPD_allocate: {
2095
440
    ConsumeToken();
2096
440
    DeclDirectiveListParserHelper Helper(this, DKind);
2097
440
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2098
440
                                  /*AllowScopeSpecifier=*/true)) {
2099
400
      SmallVector<OMPClause *, 1> Clauses;
2100
400
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2101
244
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2102
244
                    llvm::omp::Clause_enumSize + 1>
2103
244
            FirstClauses(llvm::omp::Clause_enumSize + 1);
2104
252
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2105
252
          OpenMPClauseKind CKind =
2106
252
              Tok.isAnnotation() ? 
OMPC_unknown0
2107
252
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
2108
252
          Actions.StartOpenMPClause(CKind);
2109
252
          OMPClause *Clause = ParseOpenMPClause(
2110
252
              OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2111
252
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2112
252
                    StopBeforeMatch);
2113
252
          FirstClauses[unsigned(CKind)].setInt(true);
2114
252
          if (Clause != nullptr)
2115
200
            Clauses.push_back(Clause);
2116
252
          if (Tok.is(tok::annot_pragma_openmp_end)) {
2117
244
            Actions.EndOpenMPClause();
2118
244
            break;
2119
244
          }
2120
          // Skip ',' if any.
2121
8
          if (Tok.is(tok::comma))
2122
0
            ConsumeToken();
2123
8
          Actions.EndOpenMPClause();
2124
8
        }
2125
244
        skipUntilPragmaOpenMPEnd(DKind);
2126
244
      }
2127
      // Skip the last annot_pragma_openmp_end.
2128
400
      ConsumeAnnotationToken();
2129
400
      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
2130
400
                                                  Clauses);
2131
400
    }
2132
40
    break;
2133
440
  }
2134
232
  case OMPD_requires: {
2135
232
    SourceLocation StartLoc = ConsumeToken();
2136
232
    SmallVector<OMPClause *, 5> Clauses;
2137
232
    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2138
232
                llvm::omp::Clause_enumSize + 1>
2139
232
        FirstClauses(llvm::omp::Clause_enumSize + 1);
2140
232
    if (Tok.is(tok::annot_pragma_openmp_end)) {
2141
2
      Diag(Tok, diag::err_omp_expected_clause)
2142
2
          << getOpenMPDirectiveName(OMPD_requires);
2143
2
      break;
2144
2
    }
2145
247
    
while (230
Tok.isNot(tok::annot_pragma_openmp_end)) {
2146
247
      OpenMPClauseKind CKind = Tok.isAnnotation()
2147
247
                                   ? 
OMPC_unknown0
2148
247
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
2149
247
      Actions.StartOpenMPClause(CKind);
2150
247
      OMPClause *Clause = ParseOpenMPClause(
2151
247
          OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
2152
247
      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2153
247
                StopBeforeMatch);
2154
247
      FirstClauses[unsigned(CKind)].setInt(true);
2155
247
      if (Clause != nullptr)
2156
219
        Clauses.push_back(Clause);
2157
247
      if (Tok.is(tok::annot_pragma_openmp_end)) {
2158
230
        Actions.EndOpenMPClause();
2159
230
        break;
2160
230
      }
2161
      // Skip ',' if any.
2162
17
      if (Tok.is(tok::comma))
2163
15
        ConsumeToken();
2164
17
      Actions.EndOpenMPClause();
2165
17
    }
2166
    // Consume final annot_pragma_openmp_end
2167
230
    if (Clauses.empty()) {
2168
15
      Diag(Tok, diag::err_omp_expected_clause)
2169
15
          << getOpenMPDirectiveName(OMPD_requires);
2170
15
      ConsumeAnnotationToken();
2171
15
      return nullptr;
2172
15
    }
2173
215
    ConsumeAnnotationToken();
2174
215
    return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2175
230
  }
2176
83
  case OMPD_assumes:
2177
205
  case OMPD_begin_assumes:
2178
205
    ParseOpenMPAssumesDirective(DKind, ConsumeToken());
2179
205
    break;
2180
122
  case OMPD_end_assumes:
2181
122
    ParseOpenMPEndAssumesDirective(ConsumeToken());
2182
122
    break;
2183
542
  case OMPD_declare_reduction:
2184
542
    ConsumeToken();
2185
542
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2186
384
      skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2187
      // Skip the last annot_pragma_openmp_end.
2188
384
      ConsumeAnnotationToken();
2189
384
      return Res;
2190
384
    }
2191
158
    break;
2192
304
  case OMPD_declare_mapper: {
2193
304
    ConsumeToken();
2194
304
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2195
      // Skip the last annot_pragma_openmp_end.
2196
188
      ConsumeAnnotationToken();
2197
188
      return Res;
2198
188
    }
2199
116
    break;
2200
304
  }
2201
313
  case OMPD_begin_declare_variant: {
2202
    // The syntax is:
2203
    // { #pragma omp begin declare variant clause }
2204
    // <function-declaration-or-definition-sequence>
2205
    // { #pragma omp end declare variant }
2206
    //
2207
313
    ConsumeToken();
2208
313
    OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2209
313
    ASTContext &ASTCtx = Actions.getASTContext();
2210
313
    OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
2211
313
    if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
2212
8
      while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
2213
0
        ;
2214
      // Skip the last annot_pragma_openmp_end.
2215
8
      (void)ConsumeAnnotationToken();
2216
8
      break;
2217
8
    }
2218
2219
    // Skip last tokens.
2220
305
    skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2221
2222
305
    ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2223
2224
305
    VariantMatchInfo VMI;
2225
305
    TI.getAsVariantMatchInfo(ASTCtx, VMI);
2226
2227
305
    std::function<void(StringRef)> DiagUnknownTrait =
2228
305
        [this, Loc](StringRef ISATrait) {
2229
          // TODO Track the selector locations in a way that is accessible here
2230
          // to improve the diagnostic location.
2231
2
          Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2232
2
        };
2233
305
    TargetOMPContext OMPCtx(
2234
305
        ASTCtx, std::move(DiagUnknownTrait),
2235
305
        /* CurrentFunctionDecl */ nullptr,
2236
305
        /* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>());
2237
2238
305
    if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2239
247
      Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
2240
247
      break;
2241
247
    }
2242
2243
    // Elide all the code till the matching end declare variant was found.
2244
58
    unsigned Nesting = 1;
2245
58
    SourceLocation DKLoc;
2246
58
    OpenMPDirectiveKind DK = OMPD_unknown;
2247
270k
    do {
2248
270k
      DKLoc = Tok.getLocation();
2249
270k
      DK = parseOpenMPDirectiveKind(*this);
2250
270k
      if (DK == OMPD_end_declare_variant)
2251
72
        --Nesting;
2252
269k
      else if (DK == OMPD_begin_declare_variant)
2253
20
        ++Nesting;
2254
270k
      if (!Nesting || 
isEofOrEom()269k
)
2255
58
        break;
2256
269k
      ConsumeAnyToken();
2257
269k
    } while (true);
2258
2259
0
    parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2260
58
                         DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
2261
58
    if (isEofOrEom())
2262
6
      return nullptr;
2263
52
    break;
2264
58
  }
2265
257
  case OMPD_end_declare_variant: {
2266
257
    if (Actions.isInOpenMPDeclareVariantScope())
2267
243
      Actions.ActOnOpenMPEndDeclareVariant();
2268
14
    else
2269
14
      Diag(Loc, diag::err_expected_begin_declare_variant);
2270
257
    ConsumeToken();
2271
257
    break;
2272
58
  }
2273
2.16k
  case OMPD_declare_variant:
2274
2.70k
  case OMPD_declare_simd: {
2275
    // The syntax is:
2276
    // { #pragma omp declare {simd|variant} }
2277
    // <function-declaration-or-definition>
2278
    //
2279
2.70k
    CachedTokens Toks;
2280
2.70k
    Toks.push_back(Tok);
2281
2.70k
    ConsumeToken();
2282
42.0k
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2283
39.3k
      Toks.push_back(Tok);
2284
39.3k
      ConsumeAnyToken();
2285
39.3k
    }
2286
2.70k
    Toks.push_back(Tok);
2287
2.70k
    ConsumeAnyToken();
2288
2289
2.70k
    DeclGroupPtrTy Ptr;
2290
2.70k
    if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2291
1.04k
      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2292
1.04k
                                                       TagType, Tag);
2293
1.66k
    } else if (Tok.isNot(tok::r_brace) && 
!isEofOrEom()1.65k
) {
2294
      // Here we expect to see some function declaration.
2295
1.65k
      if (AS == AS_none) {
2296
1.25k
        assert(TagType == DeclSpec::TST_unspecified);
2297
0
        MaybeParseCXX11Attributes(Attrs);
2298
1.25k
        ParsingDeclSpec PDS(*this);
2299
1.25k
        Ptr = ParseExternalDeclaration(Attrs, &PDS);
2300
1.25k
      } else {
2301
398
        Ptr =
2302
398
            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2303
398
      }
2304
1.65k
    }
2305
2.70k
    if (!Ptr) {
2306
52
      Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2307
52
          << (DKind == OMPD_declare_simd ? 
020
:
132
);
2308
52
      return DeclGroupPtrTy();
2309
52
    }
2310
2.65k
    if (DKind == OMPD_declare_simd)
2311
524
      return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2312
2.12k
    assert(DKind == OMPD_declare_variant &&
2313
2.12k
           "Expected declare variant directive only");
2314
0
    ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2315
2.12k
    return Ptr;
2316
2.65k
  }
2317
39
  case OMPD_begin_declare_target:
2318
1.22k
  case OMPD_declare_target: {
2319
1.22k
    SourceLocation DTLoc = ConsumeAnyToken();
2320
1.22k
    bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2321
1.22k
    Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2322
1.22k
    if (HasClauses)
2323
537
      ParseOMPDeclareTargetClauses(DTCI);
2324
1.22k
    bool HasImplicitMappings = DKind == OMPD_begin_declare_target ||
2325
1.22k
                               
!HasClauses1.18k
||
2326
1.22k
                               
(508
DTCI.ExplicitlyMapped.empty()508
&&
DTCI.Indirect65
);
2327
2328
    // Skip the last annot_pragma_openmp_end.
2329
1.22k
    ConsumeAnyToken();
2330
2331
1.22k
    if (HasImplicitMappings) {
2332
717
      Actions.ActOnStartOpenMPDeclareTargetContext(DTCI);
2333
717
      return nullptr;
2334
717
    }
2335
2336
506
    Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2337
506
    llvm::SmallVector<Decl *, 4> Decls;
2338
506
    for (auto &It : DTCI.ExplicitlyMapped)
2339
566
      Decls.push_back(It.first);
2340
506
    return Actions.BuildDeclaratorGroup(Decls);
2341
1.22k
  }
2342
741
  case OMPD_end_declare_target: {
2343
741
    if (!Actions.isInOpenMPDeclareTargetContext()) {
2344
36
      Diag(Tok, diag::err_omp_unexpected_directive)
2345
36
          << 1 << getOpenMPDirectiveName(DKind);
2346
36
      break;
2347
36
    }
2348
705
    const Sema::DeclareTargetContextInfo &DTCI =
2349
705
        Actions.ActOnOpenMPEndDeclareTargetDirective();
2350
705
    ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2351
705
    return nullptr;
2352
741
  }
2353
37
  case OMPD_unknown:
2354
37
    Diag(Tok, diag::err_omp_unknown_directive);
2355
37
    break;
2356
2
  case OMPD_parallel:
2357
14
  case OMPD_simd:
2358
14
  case OMPD_tile:
2359
14
  case OMPD_unroll:
2360
20
  case OMPD_task:
2361
20
  case OMPD_taskyield:
2362
20
  case OMPD_barrier:
2363
20
  case OMPD_taskwait:
2364
20
  case OMPD_taskgroup:
2365
20
  case OMPD_flush:
2366
24
  case OMPD_depobj:
2367
24
  case OMPD_scan:
2368
32
  case OMPD_for:
2369
40
  case OMPD_for_simd:
2370
44
  case OMPD_sections:
2371
44
  case OMPD_section:
2372
48
  case OMPD_single:
2373
48
  case OMPD_master:
2374
48
  case OMPD_ordered:
2375
48
  case OMPD_critical:
2376
58
  case OMPD_parallel_for:
2377
68
  case OMPD_parallel_for_simd:
2378
74
  case OMPD_parallel_sections:
2379
76
  case OMPD_parallel_master:
2380
78
  case OMPD_parallel_masked:
2381
78
  case OMPD_atomic:
2382
82
  case OMPD_target:
2383
86
  case OMPD_teams:
2384
86
  case OMPD_cancellation_point:
2385
86
  case OMPD_cancel:
2386
86
  case OMPD_target_data:
2387
86
  case OMPD_target_enter_data:
2388
86
  case OMPD_target_exit_data:
2389
88
  case OMPD_target_parallel:
2390
96
  case OMPD_target_parallel_for:
2391
100
  case OMPD_taskloop:
2392
108
  case OMPD_taskloop_simd:
2393
112
  case OMPD_master_taskloop:
2394
120
  case OMPD_master_taskloop_simd:
2395
124
  case OMPD_parallel_master_taskloop:
2396
132
  case OMPD_parallel_master_taskloop_simd:
2397
132
  case OMPD_masked_taskloop:
2398
132
  case OMPD_masked_taskloop_simd:
2399
132
  case OMPD_parallel_masked_taskloop:
2400
132
  case OMPD_parallel_masked_taskloop_simd:
2401
132
  case OMPD_distribute:
2402
132
  case OMPD_target_update:
2403
136
  case OMPD_distribute_parallel_for:
2404
144
  case OMPD_distribute_parallel_for_simd:
2405
156
  case OMPD_distribute_simd:
2406
166
  case OMPD_target_parallel_for_simd:
2407
176
  case OMPD_target_simd:
2408
176
  case OMPD_teams_distribute:
2409
180
  case OMPD_teams_distribute_simd:
2410
184
  case OMPD_teams_distribute_parallel_for_simd:
2411
188
  case OMPD_teams_distribute_parallel_for:
2412
190
  case OMPD_target_teams:
2413
196
  case OMPD_target_teams_distribute:
2414
204
  case OMPD_target_teams_distribute_parallel_for:
2415
214
  case OMPD_target_teams_distribute_parallel_for_simd:
2416
224
  case OMPD_target_teams_distribute_simd:
2417
224
  case OMPD_dispatch:
2418
224
  case OMPD_masked:
2419
224
  case OMPD_metadirective:
2420
224
  case OMPD_loop:
2421
224
  case OMPD_teams_loop:
2422
224
  case OMPD_target_teams_loop:
2423
224
  case OMPD_parallel_loop:
2424
224
  case OMPD_target_parallel_loop:
2425
224
    Diag(Tok, diag::err_omp_unexpected_directive)
2426
224
        << 1 << getOpenMPDirectiveName(DKind);
2427
224
    break;
2428
0
  default:
2429
0
    break;
2430
9.91k
  }
2431
2.10k
  
while (1.54k
Tok.isNot(tok::annot_pragma_openmp_end))
2432
560
    ConsumeAnyToken();
2433
1.54k
  ConsumeAnyToken();
2434
1.54k
  return nullptr;
2435
9.91k
}
2436
2437
/// Parsing of declarative or executable OpenMP directives.
2438
///
2439
///       threadprivate-directive:
2440
///         annot_pragma_openmp 'threadprivate' simple-variable-list
2441
///         annot_pragma_openmp_end
2442
///
2443
///       allocate-directive:
2444
///         annot_pragma_openmp 'allocate' simple-variable-list
2445
///         annot_pragma_openmp_end
2446
///
2447
///       declare-reduction-directive:
2448
///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2449
///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2450
///         ('omp_priv' '=' <expression>|<function_call>) ')']
2451
///         annot_pragma_openmp_end
2452
///
2453
///       declare-mapper-directive:
2454
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2455
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2456
///         annot_pragma_openmp_end
2457
///
2458
///       executable-directive:
2459
///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2460
///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2461
///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2462
///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2463
///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2464
///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2465
///         'master taskloop' | 'master taskloop simd' | 'parallel master
2466
///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2467
///         enter data' | 'target exit data' | 'target parallel' | 'target
2468
///         parallel for' | 'target update' | 'distribute parallel for' |
2469
///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2470
///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2471
///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2472
///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2473
///         teams distribute parallel for' | 'target teams distribute parallel
2474
///         for simd' | 'target teams distribute simd' | 'masked' {clause}
2475
///         annot_pragma_openmp_end
2476
///
2477
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
2478
264k
    ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective) {
2479
264k
  if (!ReadDirectiveWithinMetadirective)
2480
264k
    assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2481
264k
           "Not an OpenMP directive!");
2482
0
  ParsingOpenMPDirectiveRAII DirScope(*this);
2483
264k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
2484
264k
  SmallVector<OMPClause *, 5> Clauses;
2485
264k
  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2486
264k
              llvm::omp::Clause_enumSize + 1>
2487
264k
      FirstClauses(llvm::omp::Clause_enumSize + 1);
2488
264k
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2489
264k
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2490
264k
  SourceLocation Loc = ReadDirectiveWithinMetadirective
2491
264k
                           ? 
Tok.getLocation()108
2492
264k
                           : 
ConsumeAnnotationToken()264k
,
2493
264k
                 EndLoc;
2494
264k
  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2495
264k
  if (ReadDirectiveWithinMetadirective && 
DKind == OMPD_unknown108
) {
2496
2
    Diag(Tok, diag::err_omp_unknown_directive);
2497
2
    return StmtError();
2498
2
  }
2499
264k
  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2500
  // Name of critical directive.
2501
264k
  DeclarationNameInfo DirName;
2502
264k
  StmtResult Directive = StmtError();
2503
264k
  bool HasAssociatedStatement = true;
2504
2505
264k
  switch (DKind) {
2506
4
  case OMPD_nothing:
2507
4
    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2508
4
        ParsedStmtContext())
2509
1
      Diag(Tok, diag::err_omp_immediate_directive)
2510
1
        << getOpenMPDirectiveName(DKind) << 0;
2511
4
    ConsumeToken();
2512
4
    skipUntilPragmaOpenMPEnd(DKind);
2513
4
    if (Tok.is(tok::annot_pragma_openmp_end))
2514
4
      ConsumeAnnotationToken();
2515
4
    break;
2516
123
  case OMPD_metadirective: {
2517
123
    ConsumeToken();
2518
123
    SmallVector<VariantMatchInfo, 4> VMIs;
2519
2520
    // First iteration of parsing all clauses of metadirective.
2521
    // This iteration only parses and collects all context selector ignoring the
2522
    // associated directives.
2523
123
    TentativeParsingAction TPA(*this);
2524
123
    ASTContext &ASTContext = Actions.getASTContext();
2525
2526
123
    BalancedDelimiterTracker T(*this, tok::l_paren,
2527
123
                               tok::annot_pragma_openmp_end);
2528
325
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2529
210
      OpenMPClauseKind CKind = Tok.isAnnotation()
2530
210
                                   ? 
OMPC_unknown0
2531
210
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
2532
210
      SourceLocation Loc = ConsumeToken();
2533
2534
      // Parse '('.
2535
210
      if (T.expectAndConsume(diag::err_expected_lparen_after,
2536
210
                             getOpenMPClauseName(CKind).data()))
2537
0
        return Directive;
2538
2539
210
      OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2540
210
      if (CKind == OMPC_when) {
2541
        // parse and get OMPTraitInfo to pass to the When clause
2542
139
        parseOMPContextSelectors(Loc, TI);
2543
139
        if (TI.Sets.size() == 0) {
2544
4
          Diag(Tok, diag::err_omp_expected_context_selector) << "when clause";
2545
4
          TPA.Commit();
2546
4
          return Directive;
2547
4
        }
2548
2549
        // Parse ':'
2550
135
        if (Tok.is(tok::colon))
2551
133
          ConsumeAnyToken();
2552
2
        else {
2553
2
          Diag(Tok, diag::err_omp_expected_colon) << "when clause";
2554
2
          TPA.Commit();
2555
2
          return Directive;
2556
2
        }
2557
135
      }
2558
      // Skip Directive for now. We will parse directive in the second iteration
2559
204
      int paren = 0;
2560
490
      while (Tok.isNot(tok::r_paren) || 
paren != 0210
) {
2561
288
        if (Tok.is(tok::l_paren))
2562
8
          paren++;
2563
288
        if (Tok.is(tok::r_paren))
2564
8
          paren--;
2565
288
        if (Tok.is(tok::annot_pragma_openmp_end)) {
2566
2
          Diag(Tok, diag::err_omp_expected_punc)
2567
2
              << getOpenMPClauseName(CKind) << 0;
2568
2
          TPA.Commit();
2569
2
          return Directive;
2570
2
        }
2571
286
        ConsumeAnyToken();
2572
286
      }
2573
      // Parse ')'
2574
202
      if (Tok.is(tok::r_paren))
2575
202
        T.consumeClose();
2576
2577
202
      VariantMatchInfo VMI;
2578
202
      TI.getAsVariantMatchInfo(ASTContext, VMI);
2579
2580
202
      VMIs.push_back(VMI);
2581
202
    }
2582
2583
115
    TPA.Revert();
2584
    // End of the first iteration. Parser is reset to the start of metadirective
2585
2586
115
    std::function<void(StringRef)> DiagUnknownTrait =
2587
115
        [this, Loc](StringRef ISATrait) {
2588
          // TODO Track the selector locations in a way that is accessible here
2589
          // to improve the diagnostic location.
2590
5
          Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2591
5
        };
2592
115
    TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2593
115
                            /* CurrentFunctionDecl */ nullptr,
2594
115
                            ArrayRef<llvm::omp::TraitProperty>());
2595
2596
    // A single match is returned for OpenMP 5.0
2597
115
    int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2598
2599
115
    int Idx = 0;
2600
    // In OpenMP 5.0 metadirective is either replaced by another directive or
2601
    // ignored.
2602
    // TODO: In OpenMP 5.1 generate multiple directives based upon the matches
2603
    // found by getBestWhenMatchForContext.
2604
163
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2605
      // OpenMP 5.0 implementation - Skip to the best index found.
2606
161
      if (Idx++ != BestIdx) {
2607
48
        ConsumeToken();  // Consume clause name
2608
48
        T.consumeOpen(); // Consume '('
2609
48
        int paren = 0;
2610
        // Skip everything inside the clause
2611
480
        while (Tok.isNot(tok::r_paren) || 
paren != 088
) {
2612
432
          if (Tok.is(tok::l_paren))
2613
40
            paren++;
2614
432
          if (Tok.is(tok::r_paren))
2615
40
            paren--;
2616
432
          ConsumeAnyToken();
2617
432
        }
2618
        // Parse ')'
2619
48
        if (Tok.is(tok::r_paren))
2620
48
          T.consumeClose();
2621
48
        continue;
2622
48
      }
2623
2624
113
      OpenMPClauseKind CKind = Tok.isAnnotation()
2625
113
                                   ? 
OMPC_unknown0
2626
113
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
2627
113
      SourceLocation Loc = ConsumeToken();
2628
2629
      // Parse '('.
2630
113
      T.consumeOpen();
2631
2632
      // Skip ContextSelectors for when clause
2633
113
      if (CKind == OMPC_when) {
2634
90
        OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2635
        // parse and skip the ContextSelectors
2636
90
        parseOMPContextSelectors(Loc, TI);
2637
2638
        // Parse ':'
2639
90
        ConsumeAnyToken();
2640
90
      }
2641
2642
      // If no directive is passed, skip in OpenMP 5.0.
2643
      // TODO: Generate nothing directive from OpenMP 5.1.
2644
113
      if (Tok.is(tok::r_paren)) {
2645
5
        SkipUntil(tok::annot_pragma_openmp_end);
2646
5
        break;
2647
5
      }
2648
2649
      // Parse Directive
2650
108
      Directive = ParseOpenMPDeclarativeOrExecutableDirective(
2651
108
          StmtCtx,
2652
108
          /*ReadDirectiveWithinMetadirective=*/true);
2653
108
      break;
2654
113
    }
2655
115
    break;
2656
123
  }
2657
238
  case OMPD_threadprivate: {
2658
    // FIXME: Should this be permitted in C++?
2659
238
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2660
238
        ParsedStmtContext()) {
2661
4
      Diag(Tok, diag::err_omp_immediate_directive)
2662
4
          << getOpenMPDirectiveName(DKind) << 0;
2663
4
    }
2664
238
    ConsumeToken();
2665
238
    DeclDirectiveListParserHelper Helper(this, DKind);
2666
238
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2667
238
                                  /*AllowScopeSpecifier=*/false)) {
2668
234
      skipUntilPragmaOpenMPEnd(DKind);
2669
234
      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2670
234
          Loc, Helper.getIdentifiers());
2671
234
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2672
234
    }
2673
238
    SkipUntil(tok::annot_pragma_openmp_end);
2674
238
    break;
2675
123
  }
2676
314
  case OMPD_allocate: {
2677
    // FIXME: Should this be permitted in C++?
2678
314
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2679
314
        ParsedStmtContext()) {
2680
4
      Diag(Tok, diag::err_omp_immediate_directive)
2681
4
          << getOpenMPDirectiveName(DKind) << 0;
2682
4
    }
2683
314
    ConsumeToken();
2684
314
    DeclDirectiveListParserHelper Helper(this, DKind);
2685
314
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2686
314
                                  /*AllowScopeSpecifier=*/false)) {
2687
310
      SmallVector<OMPClause *, 1> Clauses;
2688
310
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2689
228
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2690
228
                    llvm::omp::Clause_enumSize + 1>
2691
228
            FirstClauses(llvm::omp::Clause_enumSize + 1);
2692
268
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2693
268
          OpenMPClauseKind CKind =
2694
268
              Tok.isAnnotation() ? 
OMPC_unknown0
2695
268
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
2696
268
          Actions.StartOpenMPClause(CKind);
2697
268
          OMPClause *Clause = ParseOpenMPClause(
2698
268
              OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2699
268
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2700
268
                    StopBeforeMatch);
2701
268
          FirstClauses[unsigned(CKind)].setInt(true);
2702
268
          if (Clause != nullptr)
2703
255
            Clauses.push_back(Clause);
2704
268
          if (Tok.is(tok::annot_pragma_openmp_end)) {
2705
228
            Actions.EndOpenMPClause();
2706
228
            break;
2707
228
          }
2708
          // Skip ',' if any.
2709
40
          if (Tok.is(tok::comma))
2710
0
            ConsumeToken();
2711
40
          Actions.EndOpenMPClause();
2712
40
        }
2713
228
        skipUntilPragmaOpenMPEnd(DKind);
2714
228
      }
2715
310
      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2716
310
          Loc, Helper.getIdentifiers(), Clauses);
2717
310
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2718
310
    }
2719
314
    SkipUntil(tok::annot_pragma_openmp_end);
2720
314
    break;
2721
123
  }
2722
162
  case OMPD_declare_reduction:
2723
162
    ConsumeToken();
2724
162
    if (DeclGroupPtrTy Res =
2725
162
            ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2726
162
      skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2727
162
      ConsumeAnyToken();
2728
162
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2729
162
    } else {
2730
0
      SkipUntil(tok::annot_pragma_openmp_end);
2731
0
    }
2732
162
    break;
2733
91
  case OMPD_declare_mapper: {
2734
91
    ConsumeToken();
2735
91
    if (DeclGroupPtrTy Res =
2736
91
            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2737
      // Skip the last annot_pragma_openmp_end.
2738
89
      ConsumeAnnotationToken();
2739
89
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2740
89
    } else {
2741
2
      SkipUntil(tok::annot_pragma_openmp_end);
2742
2
    }
2743
91
    break;
2744
123
  }
2745
833
  case OMPD_flush:
2746
1.17k
  case OMPD_depobj:
2747
1.82k
  case OMPD_scan:
2748
2.46k
  case OMPD_taskyield:
2749
3.09k
  case OMPD_barrier:
2750
3.83k
  case OMPD_taskwait:
2751
4.10k
  case OMPD_cancellation_point:
2752
4.74k
  case OMPD_cancel:
2753
6.44k
  case OMPD_target_enter_data:
2754
8.07k
  case OMPD_target_exit_data:
2755
11.5k
  case OMPD_target_update:
2756
11.7k
  case OMPD_interop:
2757
11.7k
    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2758
11.7k
        ParsedStmtContext()) {
2759
220
      Diag(Tok, diag::err_omp_immediate_directive)
2760
220
          << getOpenMPDirectiveName(DKind) << 0;
2761
220
    }
2762
11.7k
    HasAssociatedStatement = false;
2763
    // Fall through for further analysis.
2764
11.7k
    LLVM_FALLTHROUGH;
2765
35.1k
  case OMPD_parallel:
2766
39.8k
  case OMPD_simd:
2767
39.9k
  case OMPD_tile:
2768
40.0k
  case OMPD_unroll:
2769
45.4k
  case OMPD_for:
2770
50.1k
  case OMPD_for_simd:
2771
53.3k
  case OMPD_sections:
2772
55.2k
  case OMPD_single:
2773
56.4k
  case OMPD_section:
2774
57.6k
  case OMPD_master:
2775
59.1k
  case OMPD_critical:
2776
62.8k
  case OMPD_parallel_for:
2777
67.5k
  case OMPD_parallel_for_simd:
2778
70.2k
  case OMPD_parallel_sections:
2779
72.4k
  case OMPD_parallel_master:
2780
73.9k
  case OMPD_parallel_masked:
2781
77.4k
  case OMPD_task:
2782
79.0k
  case OMPD_ordered:
2783
93.1k
  case OMPD_atomic:
2784
134k
  case OMPD_target:
2785
149k
  case OMPD_teams:
2786
151k
  case OMPD_taskgroup:
2787
154k
  case OMPD_target_data:
2788
159k
  case OMPD_target_parallel:
2789
165k
  case OMPD_target_parallel_for:
2790
165k
  case OMPD_loop:
2791
165k
  case OMPD_teams_loop:
2792
165k
  case OMPD_target_teams_loop:
2793
165k
  case OMPD_parallel_loop:
2794
165k
  case OMPD_target_parallel_loop:
2795
169k
  case OMPD_taskloop:
2796
172k
  case OMPD_taskloop_simd:
2797
175k
  case OMPD_master_taskloop:
2798
176k
  case OMPD_masked_taskloop:
2799
179k
  case OMPD_master_taskloop_simd:
2800
182k
  case OMPD_masked_taskloop_simd:
2801
184k
  case OMPD_parallel_master_taskloop:
2802
186k
  case OMPD_parallel_masked_taskloop:
2803
189k
  case OMPD_parallel_master_taskloop_simd:
2804
191k
  case OMPD_parallel_masked_taskloop_simd:
2805
193k
  case OMPD_distribute:
2806
197k
  case OMPD_distribute_parallel_for:
2807
202k
  case OMPD_distribute_parallel_for_simd:
2808
206k
  case OMPD_distribute_simd:
2809
211k
  case OMPD_target_parallel_for_simd:
2810
217k
  case OMPD_target_simd:
2811
221k
  case OMPD_teams_distribute:
2812
225k
  case OMPD_teams_distribute_simd:
2813
229k
  case OMPD_teams_distribute_parallel_for_simd:
2814
233k
  case OMPD_teams_distribute_parallel_for:
2815
239k
  case OMPD_target_teams:
2816
244k
  case OMPD_target_teams_distribute:
2817
250k
  case OMPD_target_teams_distribute_parallel_for:
2818
256k
  case OMPD_target_teams_distribute_parallel_for_simd:
2819
263k
  case OMPD_target_teams_distribute_simd:
2820
263k
  case OMPD_dispatch:
2821
263k
  case OMPD_masked: {
2822
    // Special processing for flush and depobj clauses.
2823
263k
    Token ImplicitTok;
2824
263k
    bool ImplicitClauseAllowed = false;
2825
263k
    if (DKind == OMPD_flush || 
DKind == OMPD_depobj262k
) {
2826
1.17k
      ImplicitTok = Tok;
2827
1.17k
      ImplicitClauseAllowed = true;
2828
1.17k
    }
2829
263k
    ConsumeToken();
2830
    // Parse directive name of the 'critical' directive if any.
2831
263k
    if (DKind == OMPD_critical) {
2832
1.50k
      BalancedDelimiterTracker T(*this, tok::l_paren,
2833
1.50k
                                 tok::annot_pragma_openmp_end);
2834
1.50k
      if (!T.consumeOpen()) {
2835
212
        if (Tok.isAnyIdentifier()) {
2836
204
          DirName =
2837
204
              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2838
204
          ConsumeAnyToken();
2839
204
        } else {
2840
8
          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2841
8
        }
2842
212
        T.consumeClose();
2843
212
      }
2844
262k
    } else if (DKind == OMPD_cancellation_point || 
DKind == OMPD_cancel261k
) {
2845
911
      CancelRegion = parseOpenMPDirectiveKind(*this);
2846
911
      if (Tok.isNot(tok::annot_pragma_openmp_end))
2847
899
        ConsumeToken();
2848
911
    }
2849
2850
263k
    if (isOpenMPLoopDirective(DKind))
2851
121k
      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2852
263k
    if (isOpenMPSimdDirective(DKind))
2853
70.4k
      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2854
263k
    ParseScope OMPDirectiveScope(this, ScopeFlags);
2855
263k
    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2856
2857
462k
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2858
      // If we are parsing for a directive within a metadirective, the directive
2859
      // ends with a ')'.
2860
198k
      if (ReadDirectiveWithinMetadirective && 
Tok.is(tok::r_paren)112
) {
2861
387
        while (Tok.isNot(tok::annot_pragma_openmp_end))
2862
281
          ConsumeAnyToken();
2863
106
        break;
2864
106
      }
2865
198k
      bool HasImplicitClause = false;
2866
198k
      if (ImplicitClauseAllowed && 
Tok.is(tok::l_paren)532
) {
2867
404
        HasImplicitClause = true;
2868
        // Push copy of the current token back to stream to properly parse
2869
        // pseudo-clause OMPFlushClause or OMPDepobjClause.
2870
404
        PP.EnterToken(Tok, /*IsReinject*/ true);
2871
404
        PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2872
404
        ConsumeAnyToken();
2873
404
      }
2874
198k
      OpenMPClauseKind CKind = Tok.isAnnotation()
2875
198k
                                   ? 
OMPC_unknown0
2876
198k
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
2877
198k
      if (HasImplicitClause) {
2878
404
        assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2879
404
        if (DKind == OMPD_flush) {
2880
80
          CKind = OMPC_flush;
2881
324
        } else {
2882
324
          assert(DKind == OMPD_depobj &&
2883
324
                 "Expected flush or depobj directives.");
2884
0
          CKind = OMPC_depobj;
2885
324
        }
2886
404
      }
2887
      // No more implicit clauses allowed.
2888
0
      ImplicitClauseAllowed = false;
2889
198k
      Actions.StartOpenMPClause(CKind);
2890
198k
      HasImplicitClause = false;
2891
198k
      OMPClause *Clause = ParseOpenMPClause(
2892
198k
          DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2893
198k
      FirstClauses[unsigned(CKind)].setInt(true);
2894
198k
      if (Clause) {
2895
142k
        FirstClauses[unsigned(CKind)].setPointer(Clause);
2896
142k
        Clauses.push_back(Clause);
2897
142k
      }
2898
2899
      // Skip ',' if any.
2900
198k
      if (Tok.is(tok::comma))
2901
9.13k
        ConsumeToken();
2902
198k
      Actions.EndOpenMPClause();
2903
198k
    }
2904
    // End location of the directive.
2905
263k
    EndLoc = Tok.getLocation();
2906
    // Consume final annot_pragma_openmp_end.
2907
263k
    ConsumeAnnotationToken();
2908
2909
    // OpenMP [2.13.8, ordered Construct, Syntax]
2910
    // If the depend clause is specified, the ordered construct is a stand-alone
2911
    // directive.
2912
263k
    if (DKind == OMPD_ordered && 
FirstClauses[unsigned(OMPC_depend)].getInt()1.59k
) {
2913
394
      if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2914
394
          ParsedStmtContext()) {
2915
24
        Diag(Loc, diag::err_omp_immediate_directive)
2916
24
            << getOpenMPDirectiveName(DKind) << 1
2917
24
            << getOpenMPClauseName(OMPC_depend);
2918
24
      }
2919
394
      HasAssociatedStatement = false;
2920
394
    }
2921
2922
263k
    if (DKind == OMPD_tile && 
!FirstClauses[unsigned(OMPC_sizes)].getInt()78
) {
2923
1
      Diag(Loc, diag::err_omp_required_clause)
2924
1
          << getOpenMPDirectiveName(OMPD_tile) << "sizes";
2925
1
    }
2926
2927
263k
    StmtResult AssociatedStmt;
2928
263k
    if (HasAssociatedStatement) {
2929
      // The body is a block scope like in Lambdas and Blocks.
2930
251k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2931
      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2932
      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2933
      // should have at least one compound statement scope within it.
2934
251k
      ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2935
251k
      {
2936
251k
        Sema::CompoundScopeRAII Scope(Actions);
2937
251k
        AssociatedStmt = ParseStatement();
2938
2939
251k
        if (AssociatedStmt.isUsable() && 
isOpenMPLoopDirective(DKind)245k
&&
2940
251k
            
getLangOpts().OpenMPIRBuilder120k
)
2941
95
          AssociatedStmt = Actions.ActOnOpenMPLoopnest(AssociatedStmt.get());
2942
251k
      }
2943
251k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2944
251k
    } else 
if (12.1k
DKind == OMPD_target_update12.1k
||
DKind == OMPD_target_enter_data8.60k
||
2945
12.1k
               
DKind == OMPD_target_exit_data6.90k
) {
2946
6.83k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2947
6.83k
      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2948
6.83k
                        Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2949
6.83k
                                                  /*isStmtExpr=*/false));
2950
6.83k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2951
6.83k
    }
2952
263k
    Directive = Actions.ActOnOpenMPExecutableDirective(
2953
263k
        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2954
263k
        EndLoc);
2955
2956
    // Exit scope.
2957
263k
    Actions.EndOpenMPDSABlock(Directive.get());
2958
263k
    OMPDirectiveScope.Exit();
2959
263k
    break;
2960
263k
  }
2961
2
  case OMPD_declare_simd:
2962
14
  case OMPD_declare_target:
2963
14
  case OMPD_begin_declare_target:
2964
26
  case OMPD_end_declare_target:
2965
30
  case OMPD_requires:
2966
30
  case OMPD_begin_declare_variant:
2967
30
  case OMPD_end_declare_variant:
2968
30
  case OMPD_declare_variant:
2969
30
    Diag(Tok, diag::err_omp_unexpected_directive)
2970
30
        << 1 << getOpenMPDirectiveName(DKind);
2971
30
    SkipUntil(tok::annot_pragma_openmp_end);
2972
30
    break;
2973
55
  case OMPD_unknown:
2974
55
  default:
2975
55
    Diag(Tok, diag::err_omp_unknown_directive);
2976
55
    SkipUntil(tok::annot_pragma_openmp_end);
2977
55
    break;
2978
264k
  }
2979
264k
  return Directive;
2980
264k
}
2981
2982
// Parses simple list:
2983
//   simple-variable-list:
2984
//         '(' id-expression {, id-expression} ')'
2985
//
2986
bool Parser::ParseOpenMPSimpleVarList(
2987
    OpenMPDirectiveKind Kind,
2988
    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
2989
        &Callback,
2990
4.09k
    bool AllowScopeSpecifier) {
2991
  // Parse '('.
2992
4.09k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2993
4.09k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
2994
4.09k
                         getOpenMPDirectiveName(Kind).data()))
2995
28
    return true;
2996
4.07k
  bool IsCorrect = true;
2997
4.07k
  bool NoIdentIsFound = true;
2998
2999
  // Read tokens while ')' or annot_pragma_openmp_end is not found.
3000
8.48k
  while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)4.43k
) {
3001
4.41k
    CXXScopeSpec SS;
3002
4.41k
    UnqualifiedId Name;
3003
    // Read var name.
3004
4.41k
    Token PrevTok = Tok;
3005
4.41k
    NoIdentIsFound = false;
3006
3007
4.41k
    if (AllowScopeSpecifier && 
getLangOpts().CPlusPlus3.75k
&&
3008
4.41k
        ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
3009
3.74k
                                       /*ObjectHasErrors=*/false, false)) {
3010
0
      IsCorrect = false;
3011
0
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3012
0
                StopBeforeMatch);
3013
4.41k
    } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
3014
4.41k
                                  /*ObjectHadErrors=*/false, false, false,
3015
4.41k
                                  false, false, nullptr, Name)) {
3016
32
      IsCorrect = false;
3017
32
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3018
32
                StopBeforeMatch);
3019
4.38k
    } else if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)4.02k
&&
3020
4.38k
               
Tok.isNot(tok::annot_pragma_openmp_end)24
) {
3021
16
      IsCorrect = false;
3022
16
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3023
16
                StopBeforeMatch);
3024
16
      Diag(PrevTok.getLocation(), diag::err_expected)
3025
16
          << tok::identifier
3026
16
          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
3027
4.36k
    } else {
3028
4.36k
      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
3029
4.36k
    }
3030
    // Consume ','.
3031
4.41k
    if (Tok.is(tok::comma)) {
3032
362
      ConsumeToken();
3033
362
    }
3034
4.41k
  }
3035
3036
4.07k
  if (NoIdentIsFound) {
3037
16
    Diag(Tok, diag::err_expected) << tok::identifier;
3038
16
    IsCorrect = false;
3039
16
  }
3040
3041
  // Parse ')'.
3042
4.07k
  IsCorrect = !T.consumeClose() && 
IsCorrect4.05k
;
3043
3044
4.07k
  return !IsCorrect;
3045
4.09k
}
3046
3047
78
OMPClause *Parser::ParseOpenMPSizesClause() {
3048
78
  SourceLocation ClauseNameLoc = ConsumeToken();
3049
78
  SmallVector<Expr *, 4> ValExprs;
3050
3051
78
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3052
78
  if (T.consumeOpen()) {
3053
1
    Diag(Tok, diag::err_expected) << tok::l_paren;
3054
1
    return nullptr;
3055
1
  }
3056
3057
102
  
while (77
true) {
3058
102
    ExprResult Val = ParseConstantExpression();
3059
102
    if (!Val.isUsable()) {
3060
7
      T.skipToEnd();
3061
7
      return nullptr;
3062
7
    }
3063
3064
95
    ValExprs.push_back(Val.get());
3065
3066
95
    if (Tok.is(tok::r_paren) || 
Tok.is(tok::annot_pragma_openmp_end)26
)
3067
70
      break;
3068
3069
25
    ExpectAndConsume(tok::comma);
3070
25
  }
3071
3072
70
  T.consumeClose();
3073
3074
70
  return Actions.ActOnOpenMPSizesClause(
3075
70
      ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
3076
77
}
3077
3078
188
OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
3079
188
  SourceLocation Loc = Tok.getLocation();
3080
188
  ConsumeAnyToken();
3081
3082
  // Parse '('.
3083
188
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3084
188
  if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
3085
2
    return nullptr;
3086
186
  SmallVector<Sema::UsesAllocatorsData, 4> Data;
3087
266
  do {
3088
266
    ExprResult Allocator =
3089
266
        getLangOpts().CPlusPlus ? 
ParseCXXIdExpression()258
:
ParseExpression()8
;
3090
266
    if (Allocator.isInvalid()) {
3091
6
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3092
6
                StopBeforeMatch);
3093
6
      break;
3094
6
    }
3095
260
    Sema::UsesAllocatorsData &D = Data.emplace_back();
3096
260
    D.Allocator = Allocator.get();
3097
260
    if (Tok.is(tok::l_paren)) {
3098
52
      BalancedDelimiterTracker T(*this, tok::l_paren,
3099
52
                                 tok::annot_pragma_openmp_end);
3100
52
      T.consumeOpen();
3101
52
      ExprResult AllocatorTraits =
3102
52
          getLangOpts().CPlusPlus ? ParseCXXIdExpression() : 
ParseExpression()0
;
3103
52
      T.consumeClose();
3104
52
      if (AllocatorTraits.isInvalid()) {
3105
4
        SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3106
4
                  StopBeforeMatch);
3107
4
        break;
3108
4
      }
3109
48
      D.AllocatorTraits = AllocatorTraits.get();
3110
48
      D.LParenLoc = T.getOpenLocation();
3111
48
      D.RParenLoc = T.getCloseLocation();
3112
48
    }
3113
256
    if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)176
)
3114
4
      Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
3115
    // Parse ','
3116
256
    if (Tok.is(tok::comma))
3117
80
      ConsumeAnyToken();
3118
256
  } while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)84
);
3119
0
  T.consumeClose();
3120
186
  return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
3121
186
                                                T.getCloseLocation(), Data);
3122
188
}
3123
3124
/// Parsing of OpenMP clauses.
3125
///
3126
///    clause:
3127
///       if-clause | final-clause | num_threads-clause | safelen-clause |
3128
///       default-clause | private-clause | firstprivate-clause | shared-clause
3129
///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
3130
///       lastprivate-clause | reduction-clause | proc_bind-clause |
3131
///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
3132
///       mergeable-clause | flush-clause | read-clause | write-clause |
3133
///       update-clause | capture-clause | seq_cst-clause | device-clause |
3134
///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
3135
///       thread_limit-clause | priority-clause | grainsize-clause |
3136
///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
3137
///       from-clause | is_device_ptr-clause | task_reduction-clause |
3138
///       in_reduction-clause | allocator-clause | allocate-clause |
3139
///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
3140
///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
3141
///       exclusive-clause | uses_allocators-clause | use_device_addr-clause |
3142
///       has_device_addr
3143
///
3144
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
3145
199k
                                     OpenMPClauseKind CKind, bool FirstClause) {
3146
199k
  OMPClauseKind = CKind;
3147
199k
  OMPClause *Clause = nullptr;
3148
199k
  bool ErrorFound = false;
3149
199k
  bool WrongDirective = false;
3150
  // Check if clause is allowed for the given directive.
3151
199k
  if (CKind != OMPC_unknown &&
3152
199k
      
!isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)196k
) {
3153
1.51k
    Diag(Tok, diag::err_omp_unexpected_clause)
3154
1.51k
        << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3155
1.51k
    ErrorFound = true;
3156
1.51k
    WrongDirective = true;
3157
1.51k
  }
3158
3159
199k
  switch (CKind) {
3160
738
  case OMPC_final:
3161
2.25k
  case OMPC_num_threads:
3162
6.87k
  case OMPC_safelen:
3163
9.78k
  case OMPC_simdlen:
3164
17.4k
  case OMPC_collapse:
3165
18.7k
  case OMPC_ordered:
3166
20.4k
  case OMPC_num_teams:
3167
21.7k
  case OMPC_thread_limit:
3168
22.6k
  case OMPC_priority:
3169
23.4k
  case OMPC_grainsize:
3170
24.2k
  case OMPC_num_tasks:
3171
24.4k
  case OMPC_hint:
3172
24.8k
  case OMPC_allocator:
3173
25.1k
  case OMPC_depobj:
3174
25.3k
  case OMPC_detach:
3175
25.3k
  case OMPC_novariants:
3176
25.4k
  case OMPC_nocontext:
3177
25.6k
  case OMPC_filter:
3178
25.7k
  case OMPC_partial:
3179
25.7k
  case OMPC_align:
3180
    // OpenMP [2.5, Restrictions]
3181
    //  At most one num_threads clause can appear on the directive.
3182
    // OpenMP [2.8.1, simd construct, Restrictions]
3183
    //  Only one safelen  clause can appear on a simd directive.
3184
    //  Only one simdlen  clause can appear on a simd directive.
3185
    //  Only one collapse clause can appear on a simd directive.
3186
    // OpenMP [2.11.1, task Construct, Restrictions]
3187
    //  At most one if clause can appear on the directive.
3188
    //  At most one final clause can appear on the directive.
3189
    // OpenMP [teams Construct, Restrictions]
3190
    //  At most one num_teams clause can appear on the directive.
3191
    //  At most one thread_limit clause can appear on the directive.
3192
    // OpenMP [2.9.1, task Construct, Restrictions]
3193
    // At most one priority clause can appear on the directive.
3194
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
3195
    // At most one grainsize clause can appear on the directive.
3196
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
3197
    // At most one num_tasks clause can appear on the directive.
3198
    // OpenMP [2.11.3, allocate Directive, Restrictions]
3199
    // At most one allocator clause can appear on the directive.
3200
    // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
3201
    // At most one detach clause can appear on the directive.
3202
    // OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
3203
    // At most one novariants clause can appear on a dispatch directive.
3204
    // At most one nocontext clause can appear on a dispatch directive.
3205
25.7k
    if (!FirstClause) {
3206
2.04k
      Diag(Tok, diag::err_omp_more_one_clause)
3207
2.04k
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3208
2.04k
      ErrorFound = true;
3209
2.04k
    }
3210
3211
25.7k
    if ((CKind == OMPC_ordered || 
CKind == OMPC_partial24.5k
) &&
3212
25.7k
        
PP.LookAhead(/*N=*/0).isNot(tok::l_paren)1.29k
)
3213
491
      Clause = ParseOpenMPClause(CKind, WrongDirective);
3214
25.3k
    else
3215
25.3k
      Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3216
25.7k
    break;
3217
2.05k
  case OMPC_default:
3218
2.80k
  case OMPC_proc_bind:
3219
2.86k
  case OMPC_atomic_default_mem_order:
3220
3.35k
  case OMPC_order:
3221
3.50k
  case OMPC_bind:
3222
    // OpenMP [2.14.3.1, Restrictions]
3223
    //  Only a single default clause may be specified on a parallel, task or
3224
    //  teams directive.
3225
    // OpenMP [2.5, parallel Construct, Restrictions]
3226
    //  At most one proc_bind clause can appear on the directive.
3227
    // OpenMP [5.0, Requires directive, Restrictions]
3228
    //  At most one atomic_default_mem_order clause can appear
3229
    //  on the directive
3230
    // OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
3231
    // At most one bind clause can appear on a loop directive.
3232
3.50k
    if (!FirstClause && 
CKind != OMPC_order149
) {
3233
149
      Diag(Tok, diag::err_omp_more_one_clause)
3234
149
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3235
149
      ErrorFound = true;
3236
149
    }
3237
3238
3.50k
    Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3239
3.50k
    break;
3240
1.28k
  case OMPC_device:
3241
4.15k
  case OMPC_schedule:
3242
5.70k
  case OMPC_dist_schedule:
3243
8.10k
  case OMPC_defaultmap:
3244
    // OpenMP [2.7.1, Restrictions, p. 3]
3245
    //  Only one schedule clause can appear on a loop directive.
3246
    // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
3247
    //  At most one defaultmap clause can appear on the directive.
3248
    // OpenMP 5.0 [2.12.5, target construct, Restrictions]
3249
    //  At most one device clause can appear on the directive.
3250
8.10k
    if ((getLangOpts().OpenMP < 50 || 
CKind != OMPC_defaultmap6.44k
) &&
3251
8.10k
        
!FirstClause6.12k
) {
3252
183
      Diag(Tok, diag::err_omp_more_one_clause)
3253
183
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3254
183
      ErrorFound = true;
3255
183
    }
3256
8.10k
    LLVM_FALLTHROUGH;
3257
19.0k
  case OMPC_if:
3258
19.0k
    Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3259
19.0k
    break;
3260
1.62k
  case OMPC_nowait:
3261
1.81k
  case OMPC_untied:
3262
1.98k
  case OMPC_mergeable:
3263
2.52k
  case OMPC_read:
3264
3.04k
  case OMPC_write:
3265
10.3k
  case OMPC_capture:
3266
19.2k
  case OMPC_compare:
3267
20.9k
  case OMPC_seq_cst:
3268
22.5k
  case OMPC_acq_rel:
3269
24.1k
  case OMPC_acquire:
3270
25.7k
  case OMPC_release:
3271
27.3k
  case OMPC_relaxed:
3272
27.5k
  case OMPC_threads:
3273
27.6k
  case OMPC_simd:
3274
27.8k
  case OMPC_nogroup:
3275
27.8k
  case OMPC_unified_address:
3276
27.9k
  case OMPC_unified_shared_memory:
3277
27.9k
  case OMPC_reverse_offload:
3278
28.0k
  case OMPC_dynamic_allocators:
3279
28.0k
  case OMPC_full:
3280
    // OpenMP [2.7.1, Restrictions, p. 9]
3281
    //  Only one ordered clause can appear on a loop directive.
3282
    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
3283
    //  Only one nowait clause can appear on a for directive.
3284
    // OpenMP [5.0, Requires directive, Restrictions]
3285
    //   Each of the requires clauses can appear at most once on the directive.
3286
28.0k
    if (!FirstClause) {
3287
221
      Diag(Tok, diag::err_omp_more_one_clause)
3288
221
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3289
221
      ErrorFound = true;
3290
221
    }
3291
3292
28.0k
    Clause = ParseOpenMPClause(CKind, WrongDirective);
3293
28.0k
    break;
3294
675
  case OMPC_update:
3295
675
    if (!FirstClause) {
3296
22
      Diag(Tok, diag::err_omp_more_one_clause)
3297
22
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3298
22
      ErrorFound = true;
3299
22
    }
3300
3301
675
    Clause = (DKind == OMPD_depobj)
3302
675
                 ? 
ParseOpenMPSimpleClause(CKind, WrongDirective)52
3303
675
                 : 
ParseOpenMPClause(CKind, WrongDirective)623
;
3304
675
    break;
3305
11.2k
  case OMPC_private:
3306
18.6k
  case OMPC_firstprivate:
3307
27.1k
  case OMPC_lastprivate:
3308
30.3k
  case OMPC_shared:
3309
67.6k
  case OMPC_reduction:
3310
69.4k
  case OMPC_task_reduction:
3311
72.6k
  case OMPC_in_reduction:
3312
76.0k
  case OMPC_linear:
3313
78.4k
  case OMPC_aligned:
3314
78.9k
  case OMPC_copyin:
3315
79.1k
  case OMPC_copyprivate:
3316
79.2k
  case OMPC_flush:
3317
84.9k
  case OMPC_depend:
3318
106k
  case OMPC_map:
3319
109k
  case OMPC_to:
3320
110k
  case OMPC_from:
3321
110k
  case OMPC_use_device_ptr:
3322
110k
  case OMPC_use_device_addr:
3323
113k
  case OMPC_is_device_ptr:
3324
114k
  case OMPC_has_device_addr:
3325
116k
  case OMPC_allocate:
3326
118k
  case OMPC_nontemporal:
3327
118k
  case OMPC_inclusive:
3328
118k
  case OMPC_exclusive:
3329
118k
  case OMPC_affinity:
3330
118k
    Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3331
118k
    break;
3332
78
  case OMPC_sizes:
3333
78
    if (!FirstClause) {
3334
1
      Diag(Tok, diag::err_omp_more_one_clause)
3335
1
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3336
1
      ErrorFound = true;
3337
1
    }
3338
3339
78
    Clause = ParseOpenMPSizesClause();
3340
78
    break;
3341
188
  case OMPC_uses_allocators:
3342
188
    Clause = ParseOpenMPUsesAllocatorClause(DKind);
3343
188
    break;
3344
92
  case OMPC_destroy:
3345
92
    if (DKind != OMPD_interop) {
3346
44
      if (!FirstClause) {
3347
4
        Diag(Tok, diag::err_omp_more_one_clause)
3348
4
            << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3349
4
        ErrorFound = true;
3350
4
      }
3351
44
      Clause = ParseOpenMPClause(CKind, WrongDirective);
3352
44
      break;
3353
44
    }
3354
92
    
LLVM_FALLTHROUGH48
;48
3355
135
  case OMPC_init:
3356
185
  case OMPC_use:
3357
185
    Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3358
185
    break;
3359
0
  case OMPC_device_type:
3360
3.76k
  case OMPC_unknown:
3361
3.76k
    skipUntilPragmaOpenMPEnd(DKind);
3362
3.76k
    break;
3363
0
  case OMPC_threadprivate:
3364
4
  case OMPC_uniform:
3365
4
  case OMPC_match:
3366
4
    if (!WrongDirective)
3367
0
      Diag(Tok, diag::err_omp_unexpected_clause)
3368
0
          << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3369
4
    SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
3370
4
    break;
3371
0
  default:
3372
0
    break;
3373
199k
  }
3374
199k
  return ErrorFound ? 
nullptr4.09k
:
Clause195k
;
3375
199k
}
3376
3377
/// Parses simple expression in parens for single-expression clauses of OpenMP
3378
/// constructs.
3379
/// \param RLoc Returned location of right paren.
3380
ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
3381
                                         SourceLocation &RLoc,
3382
27.9k
                                         bool IsAddressOfOperand) {
3383
27.9k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3384
27.9k
  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3385
1.35k
    return ExprError();
3386
3387
26.6k
  SourceLocation ELoc = Tok.getLocation();
3388
26.6k
  ExprResult LHS(
3389
26.6k
      ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
3390
26.6k
  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3391
26.6k
  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3392
3393
  // Parse ')'.
3394
26.6k
  RLoc = Tok.getLocation();
3395
26.6k
  if (!T.consumeClose())
3396
21.1k
    RLoc = T.getCloseLocation();
3397
3398
26.6k
  return Val;
3399
27.9k
}
3400
3401
/// Parsing of OpenMP clauses with single expressions like 'final',
3402
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
3403
/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
3404
/// 'detach'.
3405
///
3406
///    final-clause:
3407
///      'final' '(' expression ')'
3408
///
3409
///    num_threads-clause:
3410
///      'num_threads' '(' expression ')'
3411
///
3412
///    safelen-clause:
3413
///      'safelen' '(' expression ')'
3414
///
3415
///    simdlen-clause:
3416
///      'simdlen' '(' expression ')'
3417
///
3418
///    collapse-clause:
3419
///      'collapse' '(' expression ')'
3420
///
3421
///    priority-clause:
3422
///      'priority' '(' expression ')'
3423
///
3424
///    grainsize-clause:
3425
///      'grainsize' '(' expression ')'
3426
///
3427
///    num_tasks-clause:
3428
///      'num_tasks' '(' expression ')'
3429
///
3430
///    hint-clause:
3431
///      'hint' '(' expression ')'
3432
///
3433
///    allocator-clause:
3434
///      'allocator' '(' expression ')'
3435
///
3436
///    detach-clause:
3437
///      'detach' '(' event-handler-expression ')'
3438
///
3439
///    align-clause
3440
///      'align' '(' positive-integer-constant ')'
3441
///
3442
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
3443
25.3k
                                               bool ParseOnly) {
3444
25.3k
  SourceLocation Loc = ConsumeToken();
3445
25.3k
  SourceLocation LLoc = Tok.getLocation();
3446
25.3k
  SourceLocation RLoc;
3447
3448
25.3k
  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
3449
3450
25.3k
  if (Val.isInvalid())
3451
5.75k
    return nullptr;
3452
3453
19.5k
  if (ParseOnly)
3454
127
    return nullptr;
3455
19.4k
  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
3456
19.5k
}
3457
3458
/// Parse indirect clause for '#pragma omp declare target' directive.
3459
///  'indirect' '[' '(' invoked-by-fptr ')' ']'
3460
/// where invoked-by-fptr is a constant boolean expression that evaluates to
3461
/// true or false at compile time.
3462
bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI,
3463
22
                                       bool ParseOnly) {
3464
22
  SourceLocation Loc = ConsumeToken();
3465
22
  SourceLocation RLoc;
3466
3467
22
  if (Tok.isNot(tok::l_paren)) {
3468
12
    if (ParseOnly)
3469
0
      return false;
3470
12
    DTCI.Indirect = nullptr;
3471
12
    return true;
3472
12
  }
3473
3474
10
  ExprResult Val =
3475
10
      ParseOpenMPParensExpr(getOpenMPClauseName(OMPC_indirect), RLoc);
3476
10
  if (Val.isInvalid())
3477
0
    return false;
3478
3479
10
  if (ParseOnly)
3480
0
    return false;
3481
3482
10
  if (!Val.get()->isValueDependent() && !Val.get()->isTypeDependent() &&
3483
10
      !Val.get()->isInstantiationDependent() &&
3484
10
      !Val.get()->containsUnexpandedParameterPack()) {
3485
10
    ExprResult Ret = Actions.CheckBooleanCondition(Loc, Val.get());
3486
10
    if (Ret.isInvalid())
3487
0
      return false;
3488
10
    llvm::APSInt Result;
3489
10
    Ret = Actions.VerifyIntegerConstantExpression(Val.get(), &Result,
3490
10
                                                  Sema::AllowFold);
3491
10
    if (Ret.isInvalid())
3492
3
      return false;
3493
7
    DTCI.Indirect = Val.get();
3494
7
    return true;
3495
10
  }
3496
0
  return false;
3497
10
}
3498
3499
/// Parsing of OpenMP clauses that use an interop-var.
3500
///
3501
/// init-clause:
3502
///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
3503
///
3504
/// destroy-clause:
3505
///   destroy(interop-var)
3506
///
3507
/// use-clause:
3508
///   use(interop-var)
3509
///
3510
/// interop-modifier:
3511
///   prefer_type(preference-list)
3512
///
3513
/// preference-list:
3514
///   foreign-runtime-id [, foreign-runtime-id]...
3515
///
3516
/// foreign-runtime-id:
3517
///   <string-literal> | <constant-integral-expression>
3518
///
3519
/// interop-type:
3520
///   target | targetsync
3521
///
3522
OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
3523
185
                                            bool ParseOnly) {
3524
185
  SourceLocation Loc = ConsumeToken();
3525
  // Parse '('.
3526
185
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3527
185
  if (T.expectAndConsume(diag::err_expected_lparen_after,
3528
185
                         getOpenMPClauseName(Kind).data()))
3529
0
    return nullptr;
3530
3531
185
  bool IsTarget = false;
3532
185
  bool IsTargetSync = false;
3533
185
  SmallVector<Expr *, 4> Prefs;
3534
3535
185
  if (Kind == OMPC_init) {
3536
3537
    // Parse optional interop-modifier.
3538
87
    if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") {
3539
30
      ConsumeToken();
3540
30
      BalancedDelimiterTracker PT(*this, tok::l_paren,
3541
30
                                  tok::annot_pragma_openmp_end);
3542
30
      if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type"))
3543
0
        return nullptr;
3544
3545
140
      
while (30
Tok.isNot(tok::r_paren)) {
3546
110
        SourceLocation Loc = Tok.getLocation();
3547
110
        ExprResult LHS = ParseCastExpression(AnyCastExpr);
3548
110
        ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
3549
110
            ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3550
110
        PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
3551
110
                                             /*DiscardedValue=*/false);
3552
110
        if (PTExpr.isUsable())
3553
109
          Prefs.push_back(PTExpr.get());
3554
1
        else
3555
1
          SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3556
1
                    StopBeforeMatch);
3557
3558
110
        if (Tok.is(tok::comma))
3559
80
          ConsumeToken();
3560
110
      }
3561
30
      PT.consumeClose();
3562
30
    }
3563
3564
87
    if (!Prefs.empty()) {
3565
30
      if (Tok.is(tok::comma))
3566
30
        ConsumeToken();
3567
0
      else
3568
0
        Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3569
30
    }
3570
3571
    // Parse the interop-types.
3572
87
    if (Optional<OMPDeclareVariantAttr::InteropType> IType =
3573
87
            parseInteropTypeList(*this)) {
3574
85
      IsTarget = IType != OMPDeclareVariantAttr::TargetSync;
3575
85
      IsTargetSync = IType != OMPDeclareVariantAttr::Target;
3576
85
      if (Tok.isNot(tok::colon))
3577
1
        Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
3578
85
    }
3579
87
    if (Tok.is(tok::colon))
3580
85
      ConsumeToken();
3581
87
  }
3582
3583
  // Parse the variable.
3584
185
  SourceLocation VarLoc = Tok.getLocation();
3585
185
  ExprResult InteropVarExpr =
3586
185
      Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3587
185
  if (!InteropVarExpr.isUsable()) {
3588
4
    SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3589
4
              StopBeforeMatch);
3590
4
  }
3591
3592
  // Parse ')'.
3593
185
  SourceLocation RLoc = Tok.getLocation();
3594
185
  if (!T.consumeClose())
3595
185
    RLoc = T.getCloseLocation();
3596
3597
185
  if (ParseOnly || !InteropVarExpr.isUsable() ||
3598
185
      
(181
Kind == OMPC_init181
&&
!IsTarget85
&&
!IsTargetSync27
))
3599
5
    return nullptr;
3600
3601
180
  if (Kind == OMPC_init)
3602
84
    return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
3603
84
                                         IsTargetSync, Loc, T.getOpenLocation(),
3604
84
                                         VarLoc, RLoc);
3605
96
  if (Kind == OMPC_use)
3606
49
    return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
3607
49
                                        T.getOpenLocation(), VarLoc, RLoc);
3608
3609
47
  if (Kind == OMPC_destroy)
3610
47
    return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc,
3611
47
                                            T.getOpenLocation(), VarLoc, RLoc);
3612
3613
0
  llvm_unreachable("Unexpected interop variable clause.");
3614
0
}
3615
3616
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
3617
///
3618
///    default-clause:
3619
///         'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')'
3620
///
3621
///    proc_bind-clause:
3622
///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
3623
///
3624
///    bind-clause:
3625
///         'bind' '(' 'teams' | 'parallel' | 'thread' ')'
3626
///
3627
///    update-clause:
3628
///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' |
3629
///         'inoutset' ')'
3630
///
3631
OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
3632
3.56k
                                           bool ParseOnly) {
3633
3.56k
  llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
3634
3.56k
  if (!Val || 
ParseOnly3.34k
)
3635
366
    return nullptr;
3636
3.19k
  if (getLangOpts().OpenMP < 51 && 
Kind == OMPC_default2.24k
&&
3637
3.19k
      
(1.27k
static_cast<DefaultKind>(Val.value().Type) == OMP_DEFAULT_private1.27k
||
3638
1.27k
       static_cast<DefaultKind>(Val.value().Type) ==
3639
1.26k
           OMP_DEFAULT_firstprivate)) {
3640
28
    Diag(Val.value().LOpen, diag::err_omp_invalid_dsa)
3641
28
        << getOpenMPClauseName(static_cast<DefaultKind>(Val.value().Type) ==
3642
28
                                       OMP_DEFAULT_private
3643
28
                                   ? 
OMPC_private14
3644
28
                                   : 
OMPC_firstprivate14
)
3645
28
        << getOpenMPClauseName(OMPC_default) << "5.1";
3646
28
    return nullptr;
3647
28
  }
3648
3.16k
  return Actions.ActOnOpenMPSimpleClause(Kind, Val.value().Type,
3649
3.16k
                                         Val.value().TypeLoc, Val.value().LOpen,
3650
3.16k
                                         Val.value().Loc, Val.value().RLoc);
3651
3.19k
}
3652
3653
/// Parsing of OpenMP clauses like 'ordered'.
3654
///
3655
///    ordered-clause:
3656
///         'ordered'
3657
///
3658
///    nowait-clause:
3659
///         'nowait'
3660
///
3661
///    untied-clause:
3662
///         'untied'
3663
///
3664
///    mergeable-clause:
3665
///         'mergeable'
3666
///
3667
///    read-clause:
3668
///         'read'
3669
///
3670
///    threads-clause:
3671
///         'threads'
3672
///
3673
///    simd-clause:
3674
///         'simd'
3675
///
3676
///    nogroup-clause:
3677
///         'nogroup'
3678
///
3679
29.2k
OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
3680
29.2k
  SourceLocation Loc = Tok.getLocation();
3681
29.2k
  ConsumeAnyToken();
3682
3683
29.2k
  if (ParseOnly)
3684
282
    return nullptr;
3685
28.9k
  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3686
29.2k
}
3687
3688
/// Parsing of OpenMP clauses with single expressions and some additional
3689
/// argument like 'schedule' or 'dist_schedule'.
3690
///
3691
///    schedule-clause:
3692
///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
3693
///      ')'
3694
///
3695
///    if-clause:
3696
///      'if' '(' [ directive-name-modifier ':' ] expression ')'
3697
///
3698
///    defaultmap:
3699
///      'defaultmap' '(' modifier [ ':' kind ] ')'
3700
///
3701
///    device-clause:
3702
///      'device' '(' [ device-modifier ':' ] expression ')'
3703
///
3704
OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
3705
                                                      OpenMPClauseKind Kind,
3706
19.0k
                                                      bool ParseOnly) {
3707
19.0k
  SourceLocation Loc = ConsumeToken();
3708
19.0k
  SourceLocation DelimLoc;
3709
  // Parse '('.
3710
19.0k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3711
19.0k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
3712
19.0k
                         getOpenMPClauseName(Kind).data()))
3713
438
    return nullptr;
3714
3715
18.6k
  ExprResult Val;
3716
18.6k
  SmallVector<unsigned, 4> Arg;
3717
18.6k
  SmallVector<SourceLocation, 4> KLoc;
3718
18.6k
  if (Kind == OMPC_schedule) {
3719
2.82k
    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3720
2.82k
    Arg.resize(NumberOfElements);
3721
2.82k
    KLoc.resize(NumberOfElements);
3722
2.82k
    Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
3723
2.82k
    Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
3724
2.82k
    Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
3725
2.82k
    unsigned KindModifier = getOpenMPSimpleClauseType(
3726
2.82k
        Kind, Tok.isAnnotation() ? 
""48
:
PP.getSpelling(Tok)2.77k
, getLangOpts());
3727
2.82k
    if (KindModifier > OMPC_SCHEDULE_unknown) {
3728
      // Parse 'modifier'
3729
176
      Arg[Modifier1] = KindModifier;
3730
176
      KLoc[Modifier1] = Tok.getLocation();
3731
176
      if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3732
176
          Tok.isNot(tok::annot_pragma_openmp_end))
3733
176
        ConsumeAnyToken();
3734
176
      if (Tok.is(tok::comma)) {
3735
        // Parse ',' 'modifier'
3736
36
        ConsumeAnyToken();
3737
36
        KindModifier = getOpenMPSimpleClauseType(
3738
36
            Kind, Tok.isAnnotation() ? 
""4
:
PP.getSpelling(Tok)32
, getLangOpts());
3739
36
        Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
3740
36
                             ? 
KindModifier28
3741
36
                             : 
(unsigned)OMPC_SCHEDULE_unknown8
;
3742
36
        KLoc[Modifier2] = Tok.getLocation();
3743
36
        if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3744
36
            Tok.isNot(tok::annot_pragma_openmp_end))
3745
32
          ConsumeAnyToken();
3746
36
      }
3747
      // Parse ':'
3748
176
      if (Tok.is(tok::colon))
3749
164
        ConsumeAnyToken();
3750
12
      else
3751
12
        Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
3752
176
      KindModifier = getOpenMPSimpleClauseType(
3753
176
          Kind, Tok.isAnnotation() ? 
""16
:
PP.getSpelling(Tok)160
, getLangOpts());
3754
176
    }
3755
2.82k
    Arg[ScheduleKind] = KindModifier;
3756
2.82k
    KLoc[ScheduleKind] = Tok.getLocation();
3757
2.82k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)2.77k
&&
3758
2.82k
        
Tok.isNot(tok::annot_pragma_openmp_end)2.77k
)
3759
2.71k
      ConsumeAnyToken();
3760
2.82k
    if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3761
2.82k
         
Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic1.85k
||
3762
2.82k
         
Arg[ScheduleKind] == OMPC_SCHEDULE_guided1.00k
) &&
3763
2.82k
        
Tok.is(tok::comma)2.16k
)
3764
1.21k
      DelimLoc = ConsumeAnyToken();
3765
15.8k
  } else if (Kind == OMPC_dist_schedule) {
3766
1.49k
    Arg.push_back(getOpenMPSimpleClauseType(
3767
1.49k
        Kind, Tok.isAnnotation() ? 
""48
:
PP.getSpelling(Tok)1.44k
, getLangOpts()));
3768
1.49k
    KLoc.push_back(Tok.getLocation());
3769
1.49k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.44k
&&
3770
1.49k
        
Tok.isNot(tok::annot_pragma_openmp_end)1.44k
)
3771
1.40k
      ConsumeAnyToken();
3772
1.49k
    if (Arg.back() == OMPC_DIST_SCHEDULE_static && 
Tok.is(tok::comma)1.35k
)
3773
885
      DelimLoc = ConsumeAnyToken();
3774
14.3k
  } else if (Kind == OMPC_defaultmap) {
3775
    // Get a defaultmap modifier
3776
2.29k
    unsigned Modifier = getOpenMPSimpleClauseType(
3777
2.29k
        Kind, Tok.isAnnotation() ? 
""120
:
PP.getSpelling(Tok)2.17k
, getLangOpts());
3778
    // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3779
    // pointer
3780
2.29k
    if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3781
120
      Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3782
2.29k
    Arg.push_back(Modifier);
3783
2.29k
    KLoc.push_back(Tok.getLocation());
3784
2.29k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)2.17k
&&
3785
2.29k
        
Tok.isNot(tok::annot_pragma_openmp_end)2.17k
)
3786
2.05k
      ConsumeAnyToken();
3787
    // Parse ':'
3788
2.29k
    if (Tok.is(tok::colon) || 
getLangOpts().OpenMP < 50842
) {
3789
1.72k
      if (Tok.is(tok::colon))
3790
1.45k
        ConsumeAnyToken();
3791
272
      else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3792
192
        Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3793
      // Get a defaultmap kind
3794
1.72k
      Arg.push_back(getOpenMPSimpleClauseType(
3795
1.72k
          Kind, Tok.isAnnotation() ? 
""320
:
PP.getSpelling(Tok)1.40k
, getLangOpts()));
3796
1.72k
      KLoc.push_back(Tok.getLocation());
3797
1.72k
      if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.64k
&&
3798
1.72k
          
Tok.isNot(tok::annot_pragma_openmp_end)1.56k
)
3799
1.24k
        ConsumeAnyToken();
3800
1.72k
    } else {
3801
570
      Arg.push_back(OMPC_DEFAULTMAP_unknown);
3802
570
      KLoc.push_back(SourceLocation());
3803
570
    }
3804
12.0k
  } else if (Kind == OMPC_device) {
3805
    // Only target executable directives support extended device construct.
3806
1.25k
    if (isOpenMPTargetExecutionDirective(DKind) && 
getLangOpts().OpenMP >= 50826
&&
3807
1.25k
        
NextToken().is(tok::colon)662
) {
3808
      // Parse optional <device modifier> ':'
3809
32
      Arg.push_back(getOpenMPSimpleClauseType(
3810
32
          Kind, Tok.isAnnotation() ? 
""0
: PP.getSpelling(Tok), getLangOpts()));
3811
32
      KLoc.push_back(Tok.getLocation());
3812
32
      ConsumeAnyToken();
3813
      // Parse ':'
3814
32
      ConsumeAnyToken();
3815
1.22k
    } else {
3816
1.22k
      Arg.push_back(OMPC_DEVICE_unknown);
3817
1.22k
      KLoc.emplace_back();
3818
1.22k
    }
3819
10.7k
  } else {
3820
10.7k
    assert(Kind == OMPC_if);
3821
0
    KLoc.push_back(Tok.getLocation());
3822
10.7k
    TentativeParsingAction TPA(*this);
3823
10.7k
    auto DK = parseOpenMPDirectiveKind(*this);
3824
10.7k
    Arg.push_back(DK);
3825
10.7k
    if (DK != OMPD_unknown) {
3826
5.60k
      ConsumeToken();
3827
5.60k
      if (Tok.is(tok::colon) && 
getLangOpts().OpenMP > 405.50k
) {
3828
5.50k
        TPA.Commit();
3829
5.50k
        DelimLoc = ConsumeToken();
3830
5.50k
      } else {
3831
96
        TPA.Revert();
3832
96
        Arg.back() = unsigned(OMPD_unknown);
3833
96
      }
3834
5.60k
    } else {
3835
5.17k
      TPA.Revert();
3836
5.17k
    }
3837
10.7k
  }
3838
3839
18.6k
  bool NeedAnExpression = (Kind == OMPC_schedule && 
DelimLoc.isValid()2.82k
) ||
3840
18.6k
                          
(17.4k
Kind == OMPC_dist_schedule17.4k
&&
DelimLoc.isValid()1.49k
) ||
3841
18.6k
                          
Kind == OMPC_if16.5k
||
Kind == OMPC_device5.76k
;
3842
18.6k
  if (NeedAnExpression) {
3843
14.1k
    SourceLocation ELoc = Tok.getLocation();
3844
14.1k
    ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3845
14.1k
    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3846
14.1k
    Val =
3847
14.1k
        Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3848
14.1k
  }
3849
3850
  // Parse ')'.
3851
18.6k
  SourceLocation RLoc = Tok.getLocation();
3852
18.6k
  if (!T.consumeClose())
3853
15.6k
    RLoc = T.getCloseLocation();
3854
3855
18.6k
  if (NeedAnExpression && 
Val.isInvalid()14.1k
)
3856
1.18k
    return nullptr;
3857
3858
17.4k
  if (ParseOnly)
3859
4
    return nullptr;
3860
17.4k
  return Actions.ActOnOpenMPSingleExprWithArgClause(
3861
17.4k
      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3862
17.4k
}
3863
3864
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3865
40.2k
                             UnqualifiedId &ReductionId) {
3866
40.2k
  if (ReductionIdScopeSpec.isEmpty()) {
3867
40.2k
    auto OOK = OO_None;
3868
40.2k
    switch (P.getCurToken().getKind()) {
3869
17.3k
    case tok::plus:
3870
17.3k
      OOK = OO_Plus;
3871
17.3k
      break;
3872
2.27k
    case tok::minus:
3873
2.27k
      OOK = OO_Minus;
3874
2.27k
      break;
3875
2.79k
    case tok::star:
3876
2.79k
      OOK = OO_Star;
3877
2.79k
      break;
3878
1.15k
    case tok::amp:
3879
1.15k
      OOK = OO_Amp;
3880
1.15k
      break;
3881
1.12k
    case tok::pipe:
3882
1.12k
      OOK = OO_Pipe;
3883
1.12k
      break;
3884
2.12k
    case tok::caret:
3885
2.12k
      OOK = OO_Caret;
3886
2.12k
      break;
3887
3.23k
    case tok::ampamp:
3888
3.23k
      OOK = OO_AmpAmp;
3889
3.23k
      break;
3890
986
    case tok::pipepipe:
3891
986
      OOK = OO_PipePipe;
3892
986
      break;
3893
9.23k
    default:
3894
9.23k
      break;
3895
40.2k
    }
3896
40.2k
    if (OOK != OO_None) {
3897
31.0k
      SourceLocation OpLoc = P.ConsumeToken();
3898
31.0k
      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3899
31.0k
      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3900
31.0k
      return false;
3901
31.0k
    }
3902
40.2k
  }
3903
9.26k
  return P.ParseUnqualifiedId(
3904
9.26k
      ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3905
9.26k
      /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3906
9.26k
      /*AllowDestructorName*/ false,
3907
9.26k
      /*AllowConstructorName*/ false,
3908
9.26k
      /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3909
40.2k
}
3910
3911
/// Checks if the token is a valid map-type-modifier.
3912
/// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
3913
12.3k
static OpenMPMapModifierKind isMapModifier(Parser &P) {
3914
12.3k
  Token Tok = P.getCurToken();
3915
12.3k
  if (!Tok.is(tok::identifier))
3916
240
    return OMPC_MAP_MODIFIER_unknown;
3917
3918
12.1k
  Preprocessor &PP = P.getPreprocessor();
3919
12.1k
  OpenMPMapModifierKind TypeModifier =
3920
12.1k
      static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3921
12.1k
          OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
3922
12.1k
  return TypeModifier;
3923
12.3k
}
3924
3925
/// Parse the mapper modifier in map, to, and from clauses.
3926
606
bool Parser::parseMapperModifier(Sema::OpenMPVarListDataTy &Data) {
3927
  // Parse '('.
3928
606
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3929
606
  if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3930
40
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3931
40
              StopBeforeMatch);
3932
40
    return true;
3933
40
  }
3934
  // Parse mapper-identifier
3935
566
  if (getLangOpts().CPlusPlus)
3936
468
    ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3937
468
                                   /*ObjectType=*/nullptr,
3938
468
                                   /*ObjectHasErrors=*/false,
3939
468
                                   /*EnteringContext=*/false);
3940
566
  if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)96
) {
3941
68
    Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3942
68
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3943
68
              StopBeforeMatch);
3944
68
    return true;
3945
68
  }
3946
498
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
3947
498
  Data.ReductionOrMapperId = DeclarationNameInfo(
3948
498
      DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3949
498
  ConsumeToken();
3950
  // Parse ')'.
3951
498
  return T.consumeClose();
3952
566
}
3953
3954
/// Parse map-type-modifiers in map clause.
3955
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3956
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3957
/// present
3958
9.52k
bool Parser::parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data) {
3959
12.8k
  while (getCurToken().isNot(tok::colon)) {
3960
12.3k
    OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3961
12.3k
    if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3962
12.3k
        
TypeModifier == OMPC_MAP_MODIFIER_close11.0k
||
3963
12.3k
        
TypeModifier == OMPC_MAP_MODIFIER_present10.3k
||
3964
12.3k
        
TypeModifier == OMPC_MAP_MODIFIER_ompx_hold10.1k
) {
3965
2.39k
      Data.MapTypeModifiers.push_back(TypeModifier);
3966
2.39k
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3967
2.39k
      ConsumeToken();
3968
9.96k
    } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3969
218
      Data.MapTypeModifiers.push_back(TypeModifier);
3970
218
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3971
218
      ConsumeToken();
3972
218
      if (parseMapperModifier(Data))
3973
20
        return true;
3974
9.74k
    } else {
3975
      // For the case of unknown map-type-modifier or a map-type.
3976
      // Map-type is followed by a colon; the function returns when it
3977
      // encounters a token followed by a colon.
3978
9.74k
      if (Tok.is(tok::comma)) {
3979
120
        Diag(Tok, diag::err_omp_map_type_modifier_missing);
3980
120
        ConsumeToken();
3981
120
        continue;
3982
120
      }
3983
      // Potential map-type token as it is followed by a colon.
3984
9.62k
      if (PP.LookAhead(0).is(tok::colon))
3985
8.99k
        return false;
3986
630
      Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3987
630
          << (getLangOpts().OpenMP >= 51 ? 
194
:
0536
)
3988
630
          << getLangOpts().OpenMPExtensions;
3989
630
      ConsumeToken();
3990
630
    }
3991
3.22k
    if (getCurToken().is(tok::comma))
3992
2.28k
      ConsumeToken();
3993
3.22k
  }
3994
502
  return false;
3995
9.52k
}
3996
3997
/// Checks if the token is a valid map-type.
3998
/// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
3999
8.99k
static OpenMPMapClauseKind isMapType(Parser &P) {
4000
8.99k
  Token Tok = P.getCurToken();
4001
  // The map-type token can be either an identifier or the C++ delete keyword.
4002
8.99k
  if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
4003
0
    return OMPC_MAP_unknown;
4004
8.99k
  Preprocessor &PP = P.getPreprocessor();
4005
8.99k
  OpenMPMapClauseKind MapType =
4006
8.99k
      static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
4007
8.99k
          OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
4008
8.99k
  return MapType;
4009
8.99k
}
4010
4011
/// Parse map-type in map clause.
4012
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
4013
/// where, map-type ::= to | from | tofrom | alloc | release | delete
4014
9.50k
static void parseMapType(Parser &P, Sema::OpenMPVarListDataTy &Data) {
4015
9.50k
  Token Tok = P.getCurToken();
4016
9.50k
  if (Tok.is(tok::colon)) {
4017
502
    P.Diag(Tok, diag::err_omp_map_type_missing);
4018
502
    return;
4019
502
  }
4020
8.99k
  Data.ExtraModifier = isMapType(P);
4021
8.99k
  if (Data.ExtraModifier == OMPC_MAP_unknown)
4022
340
    P.Diag(Tok, diag::err_omp_unknown_map_type);
4023
8.99k
  P.ConsumeToken();
4024
8.99k
}
4025
4026
/// Parses simple expression in parens for single-expression clauses of OpenMP
4027
/// constructs.
4028
95
ExprResult Parser::ParseOpenMPIteratorsExpr() {
4029
95
  assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
4030
95
         "Expected 'iterator' token.");
4031
0
  SourceLocation IteratorKwLoc = ConsumeToken();
4032
4033
95
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
4034
95
  if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
4035
6
    return ExprError();
4036
4037
89
  SourceLocation LLoc = T.getOpenLocation();
4038
89
  SmallVector<Sema::OMPIteratorData, 4> Data;
4039
184
  while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)113
) {
4040
    // Check if the type parsing is required.
4041
101
    ParsedType IteratorType;
4042
101
    if (Tok.isNot(tok::identifier) || 
NextToken().isNot(tok::equal)73
) {
4043
      // identifier '=' is not found - parse type.
4044
60
      TypeResult TR = ParseTypeName();
4045
60
      if (TR.isInvalid()) {
4046
6
        T.skipToEnd();
4047
6
        return ExprError();
4048
6
      }
4049
54
      IteratorType = TR.get();
4050
54
    }
4051
4052
    // Parse identifier.
4053
95
    IdentifierInfo *II = nullptr;
4054
95
    SourceLocation IdLoc;
4055
95
    if (Tok.is(tok::identifier)) {
4056
95
      II = Tok.getIdentifierInfo();
4057
95
      IdLoc = ConsumeToken();
4058
95
    } else {
4059
0
      Diag(Tok, diag::err_expected_unqualified_id) << 0;
4060
0
    }
4061
4062
    // Parse '='.
4063
95
    SourceLocation AssignLoc;
4064
95
    if (Tok.is(tok::equal))
4065
89
      AssignLoc = ConsumeToken();
4066
6
    else
4067
6
      Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4068
4069
    // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
4070
95
    ColonProtectionRAIIObject ColonRAII(*this);
4071
    // Parse <begin>
4072
95
    SourceLocation Loc = Tok.getLocation();
4073
95
    ExprResult LHS = ParseCastExpression(AnyCastExpr);
4074
95
    ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
4075
95
        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4076
95
    Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
4077
95
                                        /*DiscardedValue=*/false);
4078
    // Parse ':'.
4079
95
    SourceLocation ColonLoc;
4080
95
    if (Tok.is(tok::colon))
4081
89
      ColonLoc = ConsumeToken();
4082
4083
    // Parse <end>
4084
95
    Loc = Tok.getLocation();
4085
95
    LHS = ParseCastExpression(AnyCastExpr);
4086
95
    ExprResult End = Actions.CorrectDelayedTyposInExpr(
4087
95
        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4088
95
    End = Actions.ActOnFinishFullExpr(End.get(), Loc,
4089
95
                                      /*DiscardedValue=*/false);
4090
4091
95
    SourceLocation SecColonLoc;
4092
95
    ExprResult Step;
4093
    // Parse optional step.
4094
95
    if (Tok.is(tok::colon)) {
4095
      // Parse ':'
4096
32
      SecColonLoc = ConsumeToken();
4097
      // Parse <step>
4098
32
      Loc = Tok.getLocation();
4099
32
      LHS = ParseCastExpression(AnyCastExpr);
4100
32
      Step = Actions.CorrectDelayedTyposInExpr(
4101
32
          ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4102
32
      Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
4103
32
                                         /*DiscardedValue=*/false);
4104
32
    }
4105
4106
    // Parse ',' or ')'
4107
95
    if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)77
)
4108
12
      Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4109
95
    if (Tok.is(tok::comma))
4110
18
      ConsumeToken();
4111
4112
95
    Sema::OMPIteratorData &D = Data.emplace_back();
4113
95
    D.DeclIdent = II;
4114
95
    D.DeclIdentLoc = IdLoc;
4115
95
    D.Type = IteratorType;
4116
95
    D.AssignLoc = AssignLoc;
4117
95
    D.ColonLoc = ColonLoc;
4118
95
    D.SecColonLoc = SecColonLoc;
4119
95
    D.Range.Begin = Begin.get();
4120
95
    D.Range.End = End.get();
4121
95
    D.Range.Step = Step.get();
4122
95
  }
4123
4124
  // Parse ')'.
4125
83
  SourceLocation RLoc = Tok.getLocation();
4126
83
  if (!T.consumeClose())
4127
71
    RLoc = T.getCloseLocation();
4128
4129
83
  return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
4130
83
                                      Data);
4131
89
}
4132
4133
bool Parser::ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
4134
                                        Sema::OpenMPVarListDataTy &Data,
4135
147k
                                        const LangOptions &LangOpts) {
4136
  // Currently the only reserved locator is 'omp_all_memory' which is only
4137
  // allowed on a depend clause.
4138
147k
  if (Kind != OMPC_depend || 
LangOpts.OpenMP < 517.28k
)
4139
146k
    return false;
4140
4141
1.41k
  if (Tok.is(tok::identifier) &&
4142
1.41k
      
Tok.getIdentifierInfo()->isStr("omp_all_memory")1.24k
) {
4143
4144
38
    if (Data.ExtraModifier == OMPC_DEPEND_outallmemory ||
4145
38
        
Data.ExtraModifier == OMPC_DEPEND_inoutallmemory36
)
4146
2
      Diag(Tok, diag::warn_omp_more_one_omp_all_memory);
4147
36
    else if (Data.ExtraModifier != OMPC_DEPEND_out &&
4148
36
             
Data.ExtraModifier != OMPC_DEPEND_inout22
)
4149
2
      Diag(Tok, diag::err_omp_requires_out_inout_depend_type);
4150
34
    else
4151
34
      Data.ExtraModifier = Data.ExtraModifier == OMPC_DEPEND_out
4152
34
                               ? 
OMPC_DEPEND_outallmemory14
4153
34
                               : 
OMPC_DEPEND_inoutallmemory20
;
4154
38
    ConsumeToken();
4155
38
    return true;
4156
38
  }
4157
1.37k
  return false;
4158
1.41k
}
4159
4160
/// Parses clauses with list.
4161
bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
4162
                                OpenMPClauseKind Kind,
4163
                                SmallVectorImpl<Expr *> &Vars,
4164
118k
                                Sema::OpenMPVarListDataTy &Data) {
4165
118k
  UnqualifiedId UnqualifiedReductionId;
4166
118k
  bool InvalidReductionId = false;
4167
118k
  bool IsInvalidMapperModifier = false;
4168
4169
  // Parse '('.
4170
118k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
4171
118k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
4172
118k
                         getOpenMPClauseName(Kind).data()))
4173
3.96k
    return true;
4174
4175
114k
  bool HasIterator = false;
4176
114k
  bool NeedRParenForLinear = false;
4177
114k
  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
4178
114k
                                   tok::annot_pragma_openmp_end);
4179
  // Handle reduction-identifier for reduction clause.
4180
114k
  if (Kind == OMPC_reduction || 
Kind == OMPC_task_reduction79.5k
||
4181
114k
      
Kind == OMPC_in_reduction77.7k
) {
4182
40.2k
    Data.ExtraModifier = OMPC_REDUCTION_unknown;
4183
40.2k
    if (Kind == OMPC_reduction && 
getLangOpts().OpenMP >= 5035.4k
&&
4184
40.2k
        
(19.3k
Tok.is(tok::identifier)19.3k
||
Tok.is(tok::kw_default)16.1k
) &&
4185
40.2k
        
NextToken().is(tok::comma)3.27k
) {
4186
      // Parse optional reduction modifier.
4187
495
      Data.ExtraModifier =
4188
495
          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4189
495
      Data.ExtraModifierLoc = Tok.getLocation();
4190
495
      ConsumeToken();
4191
495
      assert(Tok.is(tok::comma) && "Expected comma.");
4192
0
      (void)ConsumeToken();
4193
495
    }
4194
0
    ColonProtectionRAIIObject ColonRAII(*this);
4195
40.2k
    if (getLangOpts().CPlusPlus)
4196
40.0k
      ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
4197
40.0k
                                     /*ObjectType=*/nullptr,
4198
40.0k
                                     /*ObjectHasErrors=*/false,
4199
40.0k
                                     /*EnteringContext=*/false);
4200
40.2k
    InvalidReductionId = ParseReductionId(
4201
40.2k
        *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4202
40.2k
    if (InvalidReductionId) {
4203
3.46k
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4204
3.46k
                StopBeforeMatch);
4205
3.46k
    }
4206
40.2k
    if (Tok.is(tok::colon))
4207
35.1k
      Data.ColonLoc = ConsumeToken();
4208
5.14k
    else
4209
5.14k
      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
4210
40.2k
    if (!InvalidReductionId)
4211
36.8k
      Data.ReductionOrMapperId =
4212
36.8k
          Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4213
74.6k
  } else if (Kind == OMPC_depend) {
4214
5.64k
    if (getLangOpts().OpenMP >= 50) {
4215
4.09k
      if (Tok.is(tok::identifier) && 
PP.getSpelling(Tok) == "iterator"3.94k
) {
4216
        // Handle optional dependence modifier.
4217
        // iterator(iterators-definition)
4218
        // where iterators-definition is iterator-specifier [,
4219
        // iterators-definition ]
4220
        // where iterator-specifier is [ iterator-type ] identifier =
4221
        // range-specification
4222
69
        HasIterator = true;
4223
69
        EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4224
69
        ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4225
69
        Data.DepModOrTailExpr = IteratorRes.get();
4226
        // Parse ','
4227
69
        ExpectAndConsume(tok::comma);
4228
69
      }
4229
4.09k
    }
4230
    // Handle dependency type for depend clause.
4231
5.64k
    ColonProtectionRAIIObject ColonRAII(*this);
4232
5.64k
    Data.ExtraModifier = getOpenMPSimpleClauseType(
4233
5.64k
        Kind, Tok.is(tok::identifier) ? 
PP.getSpelling(Tok)5.39k
:
""242
,
4234
5.64k
        getLangOpts());
4235
5.64k
    Data.ExtraModifierLoc = Tok.getLocation();
4236
5.64k
    if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
4237
365
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4238
365
                StopBeforeMatch);
4239
5.27k
    } else {
4240
5.27k
      ConsumeToken();
4241
      // Special processing for depend(source) clause.
4242
5.27k
      if (DKind == OMPD_ordered && 
Data.ExtraModifier == OMPC_DEPEND_source424
) {
4243
        // Parse ')'.
4244
176
        T.consumeClose();
4245
176
        return false;
4246
176
      }
4247
5.27k
    }
4248
5.46k
    if (Tok.is(tok::colon)) {
4249
4.90k
      Data.ColonLoc = ConsumeToken();
4250
4.90k
    } else {
4251
563
      Diag(Tok, DKind == OMPD_ordered ? 
diag::warn_pragma_expected_colon_r_paren24
4252
563
                                      : 
diag::warn_pragma_expected_colon539
)
4253
563
          << "dependency type";
4254
563
    }
4255
69.0k
  } else if (Kind == OMPC_linear) {
4256
    // Try to parse modifier if any.
4257
3.59k
    Data.ExtraModifier = OMPC_LINEAR_val;
4258
3.59k
    if (Tok.is(tok::identifier) && 
PP.LookAhead(0).is(tok::l_paren)3.26k
) {
4259
438
      Data.ExtraModifier =
4260
438
          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4261
438
      Data.ExtraModifierLoc = ConsumeToken();
4262
438
      LinearT.consumeOpen();
4263
438
      NeedRParenForLinear = true;
4264
438
    }
4265
65.4k
  } else if (Kind == OMPC_lastprivate) {
4266
    // Try to parse modifier if any.
4267
8.23k
    Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
4268
    // Conditional modifier allowed only in OpenMP 5.0 and not supported in
4269
    // distribute and taskloop based directives.
4270
8.23k
    if ((getLangOpts().OpenMP >= 50 && 
!isOpenMPDistributeDirective(DKind)4.79k
&&
4271
8.23k
         
!isOpenMPTaskLoopDirective(DKind)2.92k
) &&
4272
8.23k
        
Tok.is(tok::identifier)1.54k
&&
PP.LookAhead(0).is(tok::colon)1.30k
) {
4273
92
      Data.ExtraModifier =
4274
92
          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4275
92
      Data.ExtraModifierLoc = Tok.getLocation();
4276
92
      ConsumeToken();
4277
92
      assert(Tok.is(tok::colon) && "Expected colon.");
4278
0
      Data.ColonLoc = ConsumeToken();
4279
92
    }
4280
57.2k
  } else if (Kind == OMPC_map) {
4281
    // Handle map type for map clause.
4282
21.5k
    ColonProtectionRAIIObject ColonRAII(*this);
4283
4284
    // The first identifier may be a list item, a map-type or a
4285
    // map-type-modifier. The map-type can also be delete which has the same
4286
    // spelling of the C++ delete keyword.
4287
21.5k
    Data.ExtraModifier = OMPC_MAP_unknown;
4288
21.5k
    Data.ExtraModifierLoc = Tok.getLocation();
4289
4290
    // Check for presence of a colon in the map clause.
4291
21.5k
    TentativeParsingAction TPA(*this);
4292
21.5k
    bool ColonPresent = false;
4293
21.5k
    if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4294
21.5k
                  StopBeforeMatch)) {
4295
21.5k
      if (Tok.is(tok::colon))
4296
9.52k
        ColonPresent = true;
4297
21.5k
    }
4298
21.5k
    TPA.Revert();
4299
    // Only parse map-type-modifier[s] and map-type if a colon is present in
4300
    // the map clause.
4301
21.5k
    if (ColonPresent) {
4302
9.52k
      IsInvalidMapperModifier = parseMapTypeModifiers(Data);
4303
9.52k
      if (!IsInvalidMapperModifier)
4304
9.50k
        parseMapType(*this, Data);
4305
20
      else
4306
20
        SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
4307
9.52k
    }
4308
21.5k
    if (Data.ExtraModifier == OMPC_MAP_unknown) {
4309
12.9k
      Data.ExtraModifier = OMPC_MAP_tofrom;
4310
12.9k
      Data.IsMapTypeImplicit = true;
4311
12.9k
    }
4312
4313
21.5k
    if (Tok.is(tok::colon))
4314
9.52k
      Data.ColonLoc = ConsumeToken();
4315
35.6k
  } else if (Kind == OMPC_to || 
Kind == OMPC_from33.2k
) {
4316
3.70k
    while (Tok.is(tok::identifier)) {
4317
3.05k
      auto Modifier = static_cast<OpenMPMotionModifierKind>(
4318
3.05k
          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
4319
3.05k
      if (Modifier == OMPC_MOTION_MODIFIER_unknown)
4320
2.57k
        break;
4321
484
      Data.MotionModifiers.push_back(Modifier);
4322
484
      Data.MotionModifiersLoc.push_back(Tok.getLocation());
4323
484
      ConsumeToken();
4324
484
      if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4325
388
        IsInvalidMapperModifier = parseMapperModifier(Data);
4326
388
        if (IsInvalidMapperModifier)
4327
104
          break;
4328
388
      }
4329
      // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
4330
380
      if (getLangOpts().OpenMP < 51)
4331
208
        break;
4332
      // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
4333
      // TODO: Is that intentional?
4334
172
      if (Tok.is(tok::comma))
4335
54
        ConsumeToken();
4336
172
    }
4337
3.53k
    if (!Data.MotionModifiers.empty() && 
Tok.isNot(tok::colon)434
) {
4338
94
      if (!IsInvalidMapperModifier) {
4339
62
        if (getLangOpts().OpenMP < 51)
4340
44
          Diag(Tok, diag::warn_pragma_expected_colon) << ")";
4341
18
        else
4342
18
          Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
4343
62
      }
4344
94
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4345
94
                StopBeforeMatch);
4346
94
    }
4347
    // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
4348
    // that intentional?
4349
3.53k
    if ((!Data.MotionModifiers.empty() || 
getLangOpts().OpenMP >= 513.10k
) &&
4350
3.53k
        
Tok.is(tok::colon)818
)
4351
388
      Data.ColonLoc = ConsumeToken();
4352
32.1k
  } else if (Kind == OMPC_allocate ||
4353
32.1k
             
(30.1k
Kind == OMPC_affinity30.1k
&&
Tok.is(tok::identifier)112
&&
4354
30.1k
              
PP.getSpelling(Tok) == "iterator"88
)) {
4355
    // Handle optional allocator expression followed by colon delimiter.
4356
1.98k
    ColonProtectionRAIIObject ColonRAII(*this);
4357
1.98k
    TentativeParsingAction TPA(*this);
4358
    // OpenMP 5.0, 2.10.1, task Construct.
4359
    // where aff-modifier is one of the following:
4360
    // iterator(iterators-definition)
4361
1.98k
    ExprResult Tail;
4362
1.98k
    if (Kind == OMPC_allocate) {
4363
1.96k
      Tail = ParseAssignmentExpression();
4364
1.96k
    } else {
4365
26
      HasIterator = true;
4366
26
      EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4367
26
      Tail = ParseOpenMPIteratorsExpr();
4368
26
    }
4369
1.98k
    Tail = Actions.CorrectDelayedTyposInExpr(Tail);
4370
1.98k
    Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
4371
1.98k
                                       /*DiscardedValue=*/false);
4372
1.98k
    if (Tail.isUsable()) {
4373
1.14k
      if (Tok.is(tok::colon)) {
4374
623
        Data.DepModOrTailExpr = Tail.get();
4375
623
        Data.ColonLoc = ConsumeToken();
4376
623
        TPA.Commit();
4377
623
      } else {
4378
        // Colon not found, parse only list of variables.
4379
523
        TPA.Revert();
4380
523
      }
4381
1.14k
    } else {
4382
      // Parsing was unsuccessfull, revert and skip to the end of clause or
4383
      // directive.
4384
843
      TPA.Revert();
4385
843
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4386
843
                StopBeforeMatch);
4387
843
    }
4388
30.1k
  } else if (Kind == OMPC_adjust_args) {
4389
    // Handle adjust-op for adjust_args clause.
4390
54
    ColonProtectionRAIIObject ColonRAII(*this);
4391
54
    Data.ExtraModifier = getOpenMPSimpleClauseType(
4392
54
        Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : 
""0
,
4393
54
        getLangOpts());
4394
54
    Data.ExtraModifierLoc = Tok.getLocation();
4395
54
    if (Data.ExtraModifier == OMPC_ADJUST_ARGS_unknown) {
4396
0
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4397
0
                StopBeforeMatch);
4398
54
    } else {
4399
54
      ConsumeToken();
4400
54
      if (Tok.is(tok::colon))
4401
54
        Data.ColonLoc = Tok.getLocation();
4402
54
      ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4403
54
                       "adjust-op");
4404
54
    }
4405
54
  }
4406
4407
114k
  bool IsComma =
4408
114k
      (Kind != OMPC_reduction && 
Kind != OMPC_task_reduction79.3k
&&
4409
114k
       
Kind != OMPC_in_reduction77.5k
&&
Kind != OMPC_depend74.5k
&&
Kind != OMPC_map69.0k
) ||
4410
114k
      
(67.2k
Kind == OMPC_reduction67.2k
&&
!InvalidReductionId35.4k
) ||
4411
114k
      
(34.9k
Kind == OMPC_map34.9k
&&
Data.ExtraModifier != OMPC_MAP_unknown21.5k
) ||
4412
114k
      
(13.4k
Kind == OMPC_depend13.4k
&&
Data.ExtraModifier != OMPC_DEPEND_unknown5.46k
) ||
4413
114k
      
(8.32k
Kind == OMPC_adjust_args8.32k
&&
4414
8.32k
       
Data.ExtraModifier != OMPC_ADJUST_ARGS_unknown0
);
4415
114k
  const bool MayHaveTail = (Kind == OMPC_linear || 
Kind == OMPC_aligned111k
);
4416
262k
  while (IsComma || 
(120k
Tok.isNot(tok::r_paren)120k
&&
Tok.isNot(tok::colon)17.1k
&&
4417
147k
                     
Tok.isNot(tok::annot_pragma_openmp_end)14.7k
)) {
4418
147k
    ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
4419
147k
    ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
4420
147k
    if (!ParseOpenMPReservedLocator(Kind, Data, getLangOpts())) {
4421
      // Parse variable
4422
147k
      ExprResult VarExpr =
4423
147k
          Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
4424
147k
      if (VarExpr.isUsable()) {
4425
131k
        Vars.push_back(VarExpr.get());
4426
131k
      } else {
4427
16.1k
        SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4428
16.1k
                  StopBeforeMatch);
4429
16.1k
      }
4430
147k
    }
4431
    // Skip ',' if any
4432
147k
    IsComma = Tok.is(tok::comma);
4433
147k
    if (IsComma)
4434
36.2k
      ConsumeToken();
4435
111k
    else if (Tok.isNot(tok::r_paren) &&
4436
111k
             
Tok.isNot(tok::annot_pragma_openmp_end)11.0k
&&
4437
111k
             
(2.90k
!MayHaveTail2.90k
||
Tok.isNot(tok::colon)2.23k
))
4438
669
      Diag(Tok, diag::err_omp_expected_punc)
4439
669
          << ((Kind == OMPC_flush) ? 
getOpenMPDirectiveName(OMPD_flush)0
4440
669
                                   : getOpenMPClauseName(Kind))
4441
669
          << (Kind == OMPC_flush);
4442
147k
  }
4443
4444
  // Parse ')' for linear clause with modifier.
4445
114k
  if (NeedRParenForLinear)
4446
438
    LinearT.consumeClose();
4447
4448
  // Parse ':' linear-step (or ':' alignment).
4449
114k
  const bool MustHaveTail = MayHaveTail && 
Tok.is(tok::colon)6.12k
;
4450
114k
  if (MustHaveTail) {
4451
2.38k
    Data.ColonLoc = Tok.getLocation();
4452
2.38k
    SourceLocation ELoc = ConsumeToken();
4453
2.38k
    ExprResult Tail = ParseAssignmentExpression();
4454
2.38k
    Tail =
4455
2.38k
        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
4456
2.38k
    if (Tail.isUsable())
4457
2.31k
      Data.DepModOrTailExpr = Tail.get();
4458
72
    else
4459
72
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4460
72
                StopBeforeMatch);
4461
2.38k
  }
4462
4463
  // Parse ')'.
4464
114k
  Data.RLoc = Tok.getLocation();
4465
114k
  if (!T.consumeClose())
4466
105k
    Data.RLoc = T.getCloseLocation();
4467
  // Exit from scope when the iterator is used in depend clause.
4468
114k
  if (HasIterator)
4469
95
    ExitScope();
4470
114k
  return (Kind != OMPC_depend && 
Kind != OMPC_map109k
&&
Vars.empty()87.7k
) ||
4471
114k
         
(102k
MustHaveTail102k
&&
!Data.DepModOrTailExpr2.38k
) ||
InvalidReductionId102k
||
4472
114k
         
IsInvalidMapperModifier102k
;
4473
114k
}
4474
4475
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
4476
/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
4477
/// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
4478
///
4479
///    private-clause:
4480
///       'private' '(' list ')'
4481
///    firstprivate-clause:
4482
///       'firstprivate' '(' list ')'
4483
///    lastprivate-clause:
4484
///       'lastprivate' '(' list ')'
4485
///    shared-clause:
4486
///       'shared' '(' list ')'
4487
///    linear-clause:
4488
///       'linear' '(' linear-list [ ':' linear-step ] ')'
4489
///    aligned-clause:
4490
///       'aligned' '(' list [ ':' alignment ] ')'
4491
///    reduction-clause:
4492
///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
4493
///    task_reduction-clause:
4494
///       'task_reduction' '(' reduction-identifier ':' list ')'
4495
///    in_reduction-clause:
4496
///       'in_reduction' '(' reduction-identifier ':' list ')'
4497
///    copyprivate-clause:
4498
///       'copyprivate' '(' list ')'
4499
///    flush-clause:
4500
///       'flush' '(' list ')'
4501
///    depend-clause:
4502
///       'depend' '(' in | out | inout : list | source ')'
4503
///    map-clause:
4504
///       'map' '(' [ [ always [,] ] [ close [,] ]
4505
///          [ mapper '(' mapper-identifier ')' [,] ]
4506
///          to | from | tofrom | alloc | release | delete ':' ] list ')';
4507
///    to-clause:
4508
///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4509
///    from-clause:
4510
///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4511
///    use_device_ptr-clause:
4512
///       'use_device_ptr' '(' list ')'
4513
///    use_device_addr-clause:
4514
///       'use_device_addr' '(' list ')'
4515
///    is_device_ptr-clause:
4516
///       'is_device_ptr' '(' list ')'
4517
///    has_device_addr-clause:
4518
///       'has_device_addr' '(' list ')'
4519
///    allocate-clause:
4520
///       'allocate' '(' [ allocator ':' ] list ')'
4521
///    nontemporal-clause:
4522
///       'nontemporal' '(' list ')'
4523
///    inclusive-clause:
4524
///       'inclusive' '(' list ')'
4525
///    exclusive-clause:
4526
///       'exclusive' '(' list ')'
4527
///
4528
/// For 'linear' clause linear-list may have the following forms:
4529
///  list
4530
///  modifier(list)
4531
/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
4532
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
4533
                                            OpenMPClauseKind Kind,
4534
118k
                                            bool ParseOnly) {
4535
118k
  SourceLocation Loc = Tok.getLocation();
4536
118k
  SourceLocation LOpen = ConsumeToken();
4537
118k
  SmallVector<Expr *, 4> Vars;
4538
118k
  Sema::OpenMPVarListDataTy Data;
4539
4540
118k
  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
4541
16.6k
    return nullptr;
4542
4543
101k
  if (ParseOnly)
4544
611
    return nullptr;
4545
101k
  OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
4546
101k
  return Actions.ActOnOpenMPVarListClause(Kind, Vars, Locs, Data);
4547
101k
}