Coverage Report

Created: 2020-09-15 12:33

/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/UniqueVector.h"
25
#include "llvm/Frontend/OpenMP/OMPContext.h"
26
27
using namespace clang;
28
using namespace llvm::omp;
29
30
//===----------------------------------------------------------------------===//
31
// OpenMP declarative directives.
32
//===----------------------------------------------------------------------===//
33
34
namespace {
35
enum OpenMPDirectiveKindEx {
36
  OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
37
  OMPD_data,
38
  OMPD_declare,
39
  OMPD_end,
40
  OMPD_end_declare,
41
  OMPD_enter,
42
  OMPD_exit,
43
  OMPD_point,
44
  OMPD_reduction,
45
  OMPD_target_enter,
46
  OMPD_target_exit,
47
  OMPD_update,
48
  OMPD_distribute_parallel,
49
  OMPD_teams_distribute_parallel,
50
  OMPD_target_teams_distribute_parallel,
51
  OMPD_mapper,
52
  OMPD_variant,
53
  OMPD_begin,
54
  OMPD_begin_declare,
55
};
56
57
// Helper to unify the enum class OpenMPDirectiveKind with its extension
58
// the OpenMPDirectiveKindEx enum which allows to use them together as if they
59
// are unsigned values.
60
struct OpenMPDirectiveKindExWrapper {
61
4.37M
  OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
62
2.33M
  OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
63
1.87M
  bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
64
11.9M
  bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
65
0
  bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
66
1.24M
  operator unsigned() const { return Value; }
67
12.0M
  operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
68
  unsigned Value;
69
};
70
71
class DeclDirectiveListParserHelper final {
72
  SmallVector<Expr *, 4> Identifiers;
73
  Parser *P;
74
  OpenMPDirectiveKind Kind;
75
76
public:
77
  DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
78
3.02k
      : P(P), Kind(Kind) {}
79
3.17k
  void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
80
3.17k
    ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
81
3.17k
        P->getCurScope(), SS, NameInfo, Kind);
82
3.17k
    if (Res.isUsable())
83
3.07k
      Identifiers.push_back(Res.get());
84
3.17k
  }
85
2.93k
  llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
86
};
87
} // namespace
88
89
// Map token string to extended OMP token kind that are
90
// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
91
1.00M
static unsigned getOpenMPDirectiveKindEx(StringRef S) {
92
1.00M
  OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
93
1.00M
  if (DKind != OMPD_unknown)
94
769k
    return DKind;
95
233k
96
233k
  return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
97
233k
      .Case("cancellation", OMPD_cancellation)
98
233k
      .Case("data", OMPD_data)
99
233k
      .Case("declare", OMPD_declare)
100
233k
      .Case("end", OMPD_end)
101
233k
      .Case("enter", OMPD_enter)
102
233k
      .Case("exit", OMPD_exit)
103
233k
      .Case("point", OMPD_point)
104
233k
      .Case("reduction", OMPD_reduction)
105
233k
      .Case("update", OMPD_update)
106
233k
      .Case("mapper", OMPD_mapper)
107
233k
      .Case("variant", OMPD_variant)
108
233k
      .Case("begin", OMPD_begin)
109
233k
      .Default(OMPD_unknown);
110
233k
}
111
112
273k
static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
113
  // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
114
  // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
115
  // TODO: add other combined directives in topological order.
116
273k
  static const OpenMPDirectiveKindExWrapper F[][3] = {
117
273k
      {OMPD_begin, OMPD_declare, OMPD_begin_declare},
118
273k
      {OMPD_end, OMPD_declare, OMPD_end_declare},
119
273k
      {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
120
273k
      {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
121
273k
      {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
122
273k
      {OMPD_declare, OMPD_simd, OMPD_declare_simd},
123
273k
      {OMPD_declare, OMPD_target, OMPD_declare_target},
124
273k
      {OMPD_declare, OMPD_variant, OMPD_declare_variant},
125
273k
      {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
126
273k
      {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
127
273k
      {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
128
273k
      {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
129
273k
      {OMPD_distribute_parallel_for, OMPD_simd,
130
273k
       OMPD_distribute_parallel_for_simd},
131
273k
      {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
132
273k
      {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
133
273k
      {OMPD_target, OMPD_data, OMPD_target_data},
134
273k
      {OMPD_target, OMPD_enter, OMPD_target_enter},
135
273k
      {OMPD_target, OMPD_exit, OMPD_target_exit},
136
273k
      {OMPD_target, OMPD_update, OMPD_target_update},
137
273k
      {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
138
273k
      {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
139
273k
      {OMPD_for, OMPD_simd, OMPD_for_simd},
140
273k
      {OMPD_parallel, OMPD_for, OMPD_parallel_for},
141
273k
      {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
142
273k
      {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
143
273k
      {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
144
273k
      {OMPD_target, OMPD_parallel, OMPD_target_parallel},
145
273k
      {OMPD_target, OMPD_simd, OMPD_target_simd},
146
273k
      {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
147
273k
      {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
148
273k
      {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
149
273k
      {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
150
273k
      {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
151
273k
      {OMPD_teams_distribute_parallel, OMPD_for,
152
273k
       OMPD_teams_distribute_parallel_for},
153
273k
      {OMPD_teams_distribute_parallel_for, OMPD_simd,
154
273k
       OMPD_teams_distribute_parallel_for_simd},
155
273k
      {OMPD_target, OMPD_teams, OMPD_target_teams},
156
273k
      {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
157
273k
      {OMPD_target_teams_distribute, OMPD_parallel,
158
273k
       OMPD_target_teams_distribute_parallel},
159
273k
      {OMPD_target_teams_distribute, OMPD_simd,
160
273k
       OMPD_target_teams_distribute_simd},
161
273k
      {OMPD_target_teams_distribute_parallel, OMPD_for,
162
273k
       OMPD_target_teams_distribute_parallel_for},
163
273k
      {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
164
273k
       OMPD_target_teams_distribute_parallel_for_simd},
165
273k
      {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
166
273k
      {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
167
273k
      {OMPD_parallel, OMPD_master, OMPD_parallel_master},
168
273k
      {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
169
273k
      {OMPD_parallel_master_taskloop, OMPD_simd,
170
273k
       OMPD_parallel_master_taskloop_simd}};
171
273k
  enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
172
273k
  Token Tok = P.getCurToken();
173
273k
  OpenMPDirectiveKindExWrapper DKind =
174
273k
      Tok.isAnnotation()
175
320
          ? static_cast<unsigned>(OMPD_unknown)
176
273k
          : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
177
273k
  if (DKind == OMPD_unknown)
178
36.8k
    return OMPD_unknown;
179
236k
180
11.1M
  
for (unsigned I = 0; 236k
I < llvm::array_lengthof(F);
++I10.9M
) {
181
10.9M
    if (DKind != F[I][0])
182
9.89M
      continue;
183
1.00M
184
1.00M
    Tok = P.getPreprocessor().LookAhead(0);
185
1.00M
    OpenMPDirectiveKindExWrapper SDKind =
186
1.00M
        Tok.isAnnotation()
187
272k
            ? static_cast<unsigned>(OMPD_unknown)
188
729k
            : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
189
1.00M
    if (SDKind == OMPD_unknown)
190
396k
      continue;
191
604k
192
604k
    if (SDKind == F[I][1]) {
193
252k
      P.ConsumeToken();
194
252k
      DKind = F[I][2];
195
252k
    }
196
604k
  }
197
236k
  return unsigned(DKind) < llvm::omp::Directive_enumSize
198
236k
             ? static_cast<OpenMPDirectiveKind>(DKind)
199
30
             : OMPD_unknown;
200
236k
}
201
202
662
static DeclarationName parseOpenMPReductionId(Parser &P) {
203
662
  Token Tok = P.getCurToken();
204
662
  Sema &Actions = P.getActions();
205
662
  OverloadedOperatorKind OOK = OO_None;
206
  // Allow to use 'operator' keyword for C++ operators
207
662
  bool WithOperator = false;
208
662
  if (Tok.is(tok::kw_operator)) {
209
52
    P.ConsumeToken();
210
52
    Tok = P.getCurToken();
211
52
    WithOperator = true;
212
52
  }
213
662
  switch (Tok.getKind()) {
214
88
  case tok::plus: // '+'
215
88
    OOK = OO_Plus;
216
88
    break;
217
16
  case tok::minus: // '-'
218
16
    OOK = OO_Minus;
219
16
    break;
220
12
  case tok::star: // '*'
221
12
    OOK = OO_Star;
222
12
    break;
223
18
  case tok::amp: // '&'
224
18
    OOK = OO_Amp;
225
18
    break;
226
10
  case tok::pipe: // '|'
227
10
    OOK = OO_Pipe;
228
10
    break;
229
8
  case tok::caret: // '^'
230
8
    OOK = OO_Caret;
231
8
    break;
232
24
  case tok::ampamp: // '&&'
233
24
    OOK = OO_AmpAmp;
234
24
    break;
235
8
  case tok::pipepipe: // '||'
236
8
    OOK = OO_PipePipe;
237
8
    break;
238
438
  case tok::identifier: // identifier
239
438
    if (!WithOperator)
240
438
      break;
241
0
    LLVM_FALLTHROUGH;
242
40
  default:
243
40
    P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
244
40
    P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
245
40
                Parser::StopBeforeMatch);
246
40
    return DeclarationName();
247
622
  }
248
622
  P.ConsumeToken();
249
622
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
250
438
  return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
251
184
                        : DeclNames.getCXXOperatorName(OOK);
252
622
}
253
254
/// Parse 'omp declare reduction' construct.
255
///
256
///       declare-reduction-directive:
257
///        annot_pragma_openmp 'declare' 'reduction'
258
///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
259
///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
260
///        annot_pragma_openmp_end
261
/// <reduction_id> is either a base language identifier or one of the following
262
/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
263
///
264
Parser::DeclGroupPtrTy
265
678
Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
266
  // Parse '('.
267
678
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
268
678
  if (T.expectAndConsume(
269
678
          diag::err_expected_lparen_after,
270
16
          getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
271
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
272
16
    return DeclGroupPtrTy();
273
16
  }
274
662
275
662
  DeclarationName Name = parseOpenMPReductionId(*this);
276
662
  if (Name.isEmpty() && 
Tok.is(tok::annot_pragma_openmp_end)40
)
277
32
    return DeclGroupPtrTy();
278
630
279
  // Consume ':'.
280
630
  bool IsCorrect = !ExpectAndConsume(tok::colon);
281
630
282
630
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)16
)
283
8
    return DeclGroupPtrTy();
284
622
285
622
  IsCorrect = IsCorrect && 
!Name.isEmpty()614
;
286
622
287
622
  if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
288
16
    Diag(Tok.getLocation(), diag::err_expected_type);
289
16
    IsCorrect = false;
290
16
  }
291
622
292
622
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)24
)
293
16
    return DeclGroupPtrTy();
294
606
295
606
  SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
296
  // Parse list of types until ':' token.
297
726
  do {
298
726
    ColonProtectionRAIIObject ColonRAII(*this);
299
726
    SourceRange Range;
300
726
    TypeResult TR =
301
726
        ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
302
726
    if (TR.isUsable()) {
303
694
      QualType ReductionType =
304
694
          Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
305
694
      if (!ReductionType.isNull()) {
306
656
        ReductionTypes.push_back(
307
656
            std::make_pair(ReductionType, Range.getBegin()));
308
656
      }
309
32
    } else {
310
32
      SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
311
32
                StopBeforeMatch);
312
32
    }
313
726
314
726
    if (Tok.is(tok::colon) || 
Tok.is(tok::annot_pragma_openmp_end)144
)
315
606
      break;
316
120
317
    // Consume ','.
318
120
    if (ExpectAndConsume(tok::comma)) {
319
8
      IsCorrect = false;
320
8
      if (Tok.is(tok::annot_pragma_openmp_end)) {
321
0
        Diag(Tok.getLocation(), diag::err_expected_type);
322
0
        return DeclGroupPtrTy();
323
0
      }
324
120
    }
325
120
  } while (Tok.isNot(tok::annot_pragma_openmp_end));
326
606
327
606
  if (ReductionTypes.empty()) {
328
46
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
329
46
    return DeclGroupPtrTy();
330
46
  }
331
560
332
560
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
333
8
    return DeclGroupPtrTy();
334
552
335
  // Consume ':'.
336
552
  if (ExpectAndConsume(tok::colon))
337
8
    IsCorrect = false;
338
552
339
552
  if (Tok.is(tok::annot_pragma_openmp_end)) {
340
32
    Diag(Tok.getLocation(), diag::err_expected_expression);
341
32
    return DeclGroupPtrTy();
342
32
  }
343
520
344
520
  DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
345
520
      getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
346
520
347
  // Parse <combiner> expression and then parse initializer if any for each
348
  // correct type.
349
520
  unsigned I = 0, E = ReductionTypes.size();
350
608
  for (Decl *D : DRD.get()) {
351
608
    TentativeParsingAction TPA(*this);
352
608
    ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
353
608
                                    Scope::CompoundStmtScope |
354
608
                                    Scope::OpenMPDirectiveScope);
355
    // Parse <combiner> expression.
356
608
    Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
357
608
    ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
358
608
        ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
359
608
    Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
360
608
361
608
    if (CombinerResult.isInvalid() && 
Tok.isNot(tok::r_paren)54
&&
362
2
        Tok.isNot(tok::annot_pragma_openmp_end)) {
363
2
      TPA.Commit();
364
2
      IsCorrect = false;
365
2
      break;
366
2
    }
367
606
    IsCorrect = !T.consumeClose() && IsCorrect && 
CombinerResult.isUsable()590
;
368
606
    ExprResult InitializerResult;
369
606
    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
370
      // Parse <initializer> expression.
371
268
      if (Tok.is(tok::identifier) &&
372
252
          Tok.getIdentifierInfo()->isStr("initializer")) {
373
252
        ConsumeToken();
374
16
      } else {
375
16
        Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
376
16
        TPA.Commit();
377
16
        IsCorrect = false;
378
16
        break;
379
16
      }
380
      // Parse '('.
381
252
      BalancedDelimiterTracker T(*this, tok::l_paren,
382
252
                                 tok::annot_pragma_openmp_end);
383
252
      IsCorrect =
384
252
          !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
385
228
          IsCorrect;
386
252
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
387
244
        ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
388
244
                                        Scope::CompoundStmtScope |
389
244
                                        Scope::OpenMPDirectiveScope);
390
        // Parse expression.
391
244
        VarDecl *OmpPrivParm =
392
244
            Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
393
244
                                                                D);
394
        // Check if initializer is omp_priv <init_expr> or something else.
395
244
        if (Tok.is(tok::identifier) &&
396
220
            Tok.getIdentifierInfo()->isStr("omp_priv")) {
397
141
          ConsumeToken();
398
141
          ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
399
103
        } else {
400
103
          InitializerResult = Actions.ActOnFinishFullExpr(
401
103
              ParseAssignmentExpression().get(), D->getLocation(),
402
103
              /*DiscardedValue*/ false);
403
103
        }
404
244
        Actions.ActOnOpenMPDeclareReductionInitializerEnd(
405
244
            D, InitializerResult.get(), OmpPrivParm);
406
244
        if (InitializerResult.isInvalid() && 
Tok.isNot(tok::r_paren)32
&&
407
16
            Tok.isNot(tok::annot_pragma_openmp_end)) {
408
12
          TPA.Commit();
409
12
          IsCorrect = false;
410
12
          break;
411
12
        }
412
232
        IsCorrect =
413
232
            !T.consumeClose() && 
IsCorrect194
&&
!InitializerResult.isInvalid()194
;
414
232
      }
415
252
    }
416
606
417
578
    ++I;
418
    // Revert parsing if not the last type, otherwise accept it, we're done with
419
    // parsing.
420
578
    if (I != E)
421
88
      TPA.Revert();
422
490
    else
423
490
      TPA.Commit();
424
578
  }
425
520
  return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
426
520
                                                         IsCorrect);
427
520
}
428
429
141
void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
430
  // Parse declarator '=' initializer.
431
  // If a '==' or '+=' is found, suggest a fixit to '='.
432
141
  if (isTokenEqualOrEqualTypo()) {
433
115
    ConsumeToken();
434
115
435
115
    if (Tok.is(tok::code_completion)) {
436
0
      Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
437
0
      Actions.FinalizeDeclaration(OmpPrivParm);
438
0
      cutOffParsing();
439
0
      return;
440
0
    }
441
115
442
115
    PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
443
115
    ExprResult Init = ParseInitializer();
444
115
445
115
    if (Init.isInvalid()) {
446
2
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
447
2
      Actions.ActOnInitializerError(OmpPrivParm);
448
113
    } else {
449
113
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
450
113
                                   /*DirectInit=*/false);
451
113
    }
452
26
  } else if (Tok.is(tok::l_paren)) {
453
    // Parse C++ direct initializer: '(' expression-list ')'
454
0
    BalancedDelimiterTracker T(*this, tok::l_paren);
455
0
    T.consumeOpen();
456
0
457
0
    ExprVector Exprs;
458
0
    CommaLocsTy CommaLocs;
459
0
460
0
    SourceLocation LParLoc = T.getOpenLocation();
461
0
    auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
462
0
      QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
463
0
          getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
464
0
          OmpPrivParm->getLocation(), Exprs, LParLoc);
465
0
      CalledSignatureHelp = true;
466
0
      return PreferredType;
467
0
    };
468
0
    if (ParseExpressionList(Exprs, CommaLocs, [&] {
469
0
          PreferredType.enterFunctionArgument(Tok.getLocation(),
470
0
                                              RunSignatureHelp);
471
0
        })) {
472
0
      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
473
0
        RunSignatureHelp();
474
0
      Actions.ActOnInitializerError(OmpPrivParm);
475
0
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
476
0
    } else {
477
      // Match the ')'.
478
0
      SourceLocation RLoc = Tok.getLocation();
479
0
      if (!T.consumeClose())
480
0
        RLoc = T.getCloseLocation();
481
0
482
0
      assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
483
0
             "Unexpected number of commas!");
484
0
485
0
      ExprResult Initializer =
486
0
          Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
487
0
      Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
488
0
                                   /*DirectInit=*/true);
489
0
    }
490
26
  } else if (getLangOpts().CPlusPlus11 && 
Tok.is(tok::l_brace)16
) {
491
    // Parse C++0x braced-init-list.
492
0
    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
493
0
494
0
    ExprResult Init(ParseBraceInitializer());
495
0
496
0
    if (Init.isInvalid()) {
497
0
      Actions.ActOnInitializerError(OmpPrivParm);
498
0
    } else {
499
0
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
500
0
                                   /*DirectInit=*/true);
501
0
    }
502
26
  } else {
503
26
    Actions.ActOnUninitializedDecl(OmpPrivParm);
504
26
  }
505
141
}
506
507
/// Parses 'omp declare mapper' directive.
508
///
509
///       declare-mapper-directive:
510
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
511
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
512
///         annot_pragma_openmp_end
513
/// <mapper-identifier> and <var> are base language identifiers.
514
///
515
Parser::DeclGroupPtrTy
516
362
Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
517
362
  bool IsCorrect = true;
518
  // Parse '('
519
362
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
520
362
  if (T.expectAndConsume(diag::err_expected_lparen_after,
521
16
                         getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
522
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
523
16
    return DeclGroupPtrTy();
524
16
  }
525
346
526
  // Parse <mapper-identifier>
527
346
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
528
346
  DeclarationName MapperId;
529
346
  if (PP.LookAhead(0).is(tok::colon)) {
530
262
    if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)40
) {
531
8
      Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
532
8
      IsCorrect = false;
533
254
    } else {
534
254
      MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
535
254
    }
536
262
    ConsumeToken();
537
    // Consume ':'.
538
262
    ExpectAndConsume(tok::colon);
539
84
  } else {
540
    // If no mapper identifier is provided, its name is "default" by default
541
84
    MapperId =
542
84
        DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
543
84
  }
544
346
545
346
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
546
0
    return DeclGroupPtrTy();
547
346
548
  // Parse <type> <var>
549
346
  DeclarationName VName;
550
346
  QualType MapperType;
551
346
  SourceRange Range;
552
346
  TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
553
346
  if (ParsedType.isUsable())
554
294
    MapperType =
555
294
        Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
556
346
  if (MapperType.isNull())
557
60
    IsCorrect = false;
558
346
  if (!IsCorrect) {
559
68
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
560
68
    return DeclGroupPtrTy();
561
68
  }
562
278
563
  // Consume ')'.
564
278
  IsCorrect &= !T.consumeClose();
565
278
  if (!IsCorrect) {
566
8
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
567
8
    return DeclGroupPtrTy();
568
8
  }
569
270
570
  // Enter scope.
571
270
  DeclarationNameInfo DirName;
572
270
  SourceLocation Loc = Tok.getLocation();
573
270
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
574
270
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
575
270
  ParseScope OMPDirectiveScope(this, ScopeFlags);
576
270
  Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
577
270
578
  // Add the mapper variable declaration.
579
270
  ExprResult MapperVarRef = Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
580
270
      getCurScope(), MapperType, Range.getBegin(), VName);
581
270
582
  // Parse map clauses.
583
270
  SmallVector<OMPClause *, 6> Clauses;
584
554
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
585
284
    OpenMPClauseKind CKind = Tok.isAnnotation()
586
0
                                 ? OMPC_unknown
587
284
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
588
284
    Actions.StartOpenMPClause(CKind);
589
284
    OMPClause *Clause =
590
284
        ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
591
284
    if (Clause)
592
266
      Clauses.push_back(Clause);
593
18
    else
594
18
      IsCorrect = false;
595
    // Skip ',' if any.
596
284
    if (Tok.is(tok::comma))
597
0
      ConsumeToken();
598
284
    Actions.EndOpenMPClause();
599
284
  }
600
270
  if (Clauses.empty()) {
601
16
    Diag(Tok, diag::err_omp_expected_clause)
602
16
        << getOpenMPDirectiveName(OMPD_declare_mapper);
603
16
    IsCorrect = false;
604
16
  }
605
270
606
  // Exit scope.
607
270
  Actions.EndOpenMPDSABlock(nullptr);
608
270
  OMPDirectiveScope.Exit();
609
270
  DeclGroupPtrTy DG = Actions.ActOnOpenMPDeclareMapperDirective(
610
270
      getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
611
270
      Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
612
270
  if (!IsCorrect)
613
26
    return DeclGroupPtrTy();
614
244
615
244
  return DG;
616
244
}
617
618
TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
619
                                                   DeclarationName &Name,
620
346
                                                   AccessSpecifier AS) {
621
  // Parse the common declaration-specifiers piece.
622
346
  Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
623
346
  DeclSpec DS(AttrFactory);
624
346
  ParseSpecifierQualifierList(DS, AS, DSC);
625
346
626
  // Parse the declarator.
627
346
  DeclaratorContext Context = DeclaratorContext::PrototypeContext;
628
346
  Declarator DeclaratorInfo(DS, Context);
629
346
  ParseDeclarator(DeclaratorInfo);
630
346
  Range = DeclaratorInfo.getSourceRange();
631
346
  if (DeclaratorInfo.getIdentifier() == nullptr) {
632
32
    Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
633
32
    return true;
634
32
  }
635
314
  Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
636
314
637
314
  return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
638
314
}
639
640
namespace {
641
/// RAII that recreates function context for correct parsing of clauses of
642
/// 'declare simd' construct.
643
/// OpenMP, 2.8.2 declare simd Construct
644
/// The expressions appearing in the clauses of this directive are evaluated in
645
/// the scope of the arguments of the function declaration or definition.
646
class FNContextRAII final {
647
  Parser &P;
648
  Sema::CXXThisScopeRAII *ThisScope;
649
  Parser::MultiParseScope Scopes;
650
  bool HasFunScope = false;
651
  FNContextRAII() = delete;
652
  FNContextRAII(const FNContextRAII &) = delete;
653
  FNContextRAII &operator=(const FNContextRAII &) = delete;
654
655
public:
656
2.27k
  FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P), Scopes(P) {
657
2.27k
    Decl *D = *Ptr.get().begin();
658
2.27k
    NamedDecl *ND = dyn_cast<NamedDecl>(D);
659
2.27k
    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
660
2.27k
    Sema &Actions = P.getActions();
661
2.27k
662
    // Allow 'this' within late-parsed attributes.
663
2.27k
    ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
664
2.27k
                                           ND && 
ND->isCXXInstanceMember()2.27k
);
665
2.27k
666
    // If the Decl is templatized, add template parameters to scope.
667
    // FIXME: Track CurTemplateDepth?
668
2.27k
    P.ReenterTemplateScopes(Scopes, D);
669
2.27k
670
    // If the Decl is on a function, add function parameters to the scope.
671
2.27k
    if (D->isFunctionOrFunctionTemplate()) {
672
2.25k
      HasFunScope = true;
673
2.25k
      Scopes.Enter(Scope::FnScope | Scope::DeclScope |
674
2.25k
                   Scope::CompoundStmtScope);
675
2.25k
      Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
676
2.25k
    }
677
2.27k
  }
678
2.27k
  ~FNContextRAII() {
679
2.27k
    if (HasFunScope)
680
2.25k
      P.getActions().ActOnExitFunctionContext();
681
2.27k
    delete ThisScope;
682
2.27k
  }
683
};
684
} // namespace
685
686
/// Parses clauses for 'declare simd' directive.
687
///    clause:
688
///      'inbranch' | 'notinbranch'
689
///      'simdlen' '(' <expr> ')'
690
///      { 'uniform' '(' <argument_list> ')' }
691
///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
692
///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
693
static bool parseDeclareSimdClauses(
694
    Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
695
    SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
696
    SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
697
482
    SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
698
482
  SourceRange BSRange;
699
482
  const Token &Tok = P.getCurToken();
700
482
  bool IsError = false;
701
1.13k
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
702
656
    if (Tok.isNot(tok::identifier))
703
6
      break;
704
650
    OMPDeclareSimdDeclAttr::BranchStateTy Out;
705
650
    IdentifierInfo *II = Tok.getIdentifierInfo();
706
650
    StringRef ClauseName = II->getName();
707
    // Parse 'inranch|notinbranch' clauses.
708
650
    if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
709
140
      if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && 
BS != Out12
) {
710
4
        P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
711
4
            << ClauseName
712
4
            << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
713
4
        IsError = true;
714
4
      }
715
140
      BS = Out;
716
140
      BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
717
140
      P.ConsumeToken();
718
510
    } else if (ClauseName.equals("simdlen")) {
719
148
      if (SimdLen.isUsable()) {
720
2
        P.Diag(Tok, diag::err_omp_more_one_clause)
721
2
            << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
722
2
        IsError = true;
723
2
      }
724
148
      P.ConsumeToken();
725
148
      SourceLocation RLoc;
726
148
      SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
727
148
      if (SimdLen.isInvalid())
728
18
        IsError = true;
729
362
    } else {
730
362
      OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
731
362
      if (CKind == OMPC_uniform || 
CKind == OMPC_aligned304
||
732
360
          
CKind == OMPC_linear170
) {
733
360
        Parser::OpenMPVarListDataTy Data;
734
360
        SmallVectorImpl<Expr *> *Vars = &Uniforms;
735
360
        if (CKind == OMPC_aligned) {
736
134
          Vars = &Aligneds;
737
226
        } else if (CKind == OMPC_linear) {
738
168
          Data.ExtraModifier = OMPC_LINEAR_val;
739
168
          Vars = &Linears;
740
168
        }
741
360
742
360
        P.ConsumeToken();
743
360
        if (P.ParseOpenMPVarList(OMPD_declare_simd,
744
360
                                 getOpenMPClauseKind(ClauseName), *Vars, Data))
745
36
          IsError = true;
746
360
        if (CKind == OMPC_aligned) {
747
134
          Alignments.append(Aligneds.size() - Alignments.size(),
748
134
                            Data.DepModOrTailExpr);
749
226
        } else if (CKind == OMPC_linear) {
750
168
          assert(0 <= Data.ExtraModifier &&
751
168
                 Data.ExtraModifier <= OMPC_LINEAR_unknown &&
752
168
                 "Unexpected linear modifier.");
753
168
          if (P.getActions().CheckOpenMPLinearModifier(
754
168
                  static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
755
168
                  Data.ExtraModifierLoc))
756
2
            Data.ExtraModifier = OMPC_LINEAR_val;
757
168
          LinModifiers.append(Linears.size() - LinModifiers.size(),
758
168
                              Data.ExtraModifier);
759
168
          Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr);
760
168
        }
761
360
      } else
762
        // TODO: add parsing of other clauses.
763
2
        break;
764
648
    }
765
    // Skip ',' if any.
766
648
    if (Tok.is(tok::comma))
767
14
      P.ConsumeToken();
768
648
  }
769
482
  return IsError;
770
482
}
771
772
/// Parse clauses for '#pragma omp declare simd'.
773
Parser::DeclGroupPtrTy
774
Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
775
482
                                   CachedTokens &Toks, SourceLocation Loc) {
776
482
  PP.EnterToken(Tok, /*IsReinject*/ true);
777
482
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
778
482
                      /*IsReinject*/ true);
779
  // Consume the previously pushed token.
780
482
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
781
482
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
782
482
783
482
  FNContextRAII FnContext(*this, Ptr);
784
482
  OMPDeclareSimdDeclAttr::BranchStateTy BS =
785
482
      OMPDeclareSimdDeclAttr::BS_Undefined;
786
482
  ExprResult Simdlen;
787
482
  SmallVector<Expr *, 4> Uniforms;
788
482
  SmallVector<Expr *, 4> Aligneds;
789
482
  SmallVector<Expr *, 4> Alignments;
790
482
  SmallVector<Expr *, 4> Linears;
791
482
  SmallVector<unsigned, 4> LinModifiers;
792
482
  SmallVector<Expr *, 4> Steps;
793
482
  bool IsError =
794
482
      parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
795
482
                              Alignments, Linears, LinModifiers, Steps);
796
482
  skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
797
  // Skip the last annot_pragma_openmp_end.
798
482
  SourceLocation EndLoc = ConsumeAnnotationToken();
799
482
  if (IsError)
800
54
    return Ptr;
801
428
  return Actions.ActOnOpenMPDeclareSimdDirective(
802
428
      Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
803
428
      LinModifiers, Steps, SourceRange(Loc, EndLoc));
804
428
}
805
806
namespace {
807
/// Constant used in the diagnostics to distinguish the levels in an OpenMP
808
/// contexts: selector-set={selector(trait, ...), ...}, ....
809
enum OMPContextLvl {
810
  CONTEXT_SELECTOR_SET_LVL = 0,
811
  CONTEXT_SELECTOR_LVL = 1,
812
  CONTEXT_TRAIT_LVL = 2,
813
};
814
815
8
static StringRef stringLiteralParser(Parser &P) {
816
8
  ExprResult Res = P.ParseStringLiteralExpression(true);
817
8
  return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : 
""0
;
818
8
}
819
820
static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
821
7.27k
                                       OMPContextLvl Lvl) {
822
7.27k
  if (Tok.is(tok::identifier)) {
823
7.13k
    llvm::SmallString<16> Buffer;
824
7.13k
    StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
825
7.13k
    (void)P.ConsumeToken();
826
7.13k
    return Name;
827
7.13k
  }
828
132
829
132
  if (tok::isStringLiteral(Tok.getKind()))
830
8
    return stringLiteralParser(P);
831
124
832
124
  P.Diag(Tok.getLocation(),
833
124
         diag::warn_omp_declare_variant_string_literal_or_identifier)
834
124
      << Lvl;
835
124
  return "";
836
124
}
837
838
static bool checkForDuplicates(Parser &P, StringRef Name,
839
                               SourceLocation NameLoc,
840
                               llvm::StringMap<SourceLocation> &Seen,
841
6.97k
                               OMPContextLvl Lvl) {
842
6.97k
  auto Res = Seen.try_emplace(Name, NameLoc);
843
6.97k
  if (Res.second)
844
6.95k
    return false;
845
22
846
  // Each trait-set-selector-name, trait-selector-name and trait-name can
847
  // only be specified once.
848
22
  P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
849
22
      << Lvl << Name;
850
22
  P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
851
22
      << Lvl << Name;
852
22
  return true;
853
22
}
854
} // namespace
855
856
void Parser::parseOMPTraitPropertyKind(
857
    OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set,
858
2.92k
    llvm::omp::TraitSelector Selector, llvm::StringMap<SourceLocation> &Seen) {
859
2.92k
  TIProperty.Kind = TraitProperty::invalid;
860
2.92k
861
2.92k
  SourceLocation NameLoc = Tok.getLocation();
862
2.92k
  StringRef Name =
863
2.92k
      getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
864
2.92k
  if (Name.empty()) {
865
60
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
866
60
        << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
867
60
    return;
868
60
  }
869
2.86k
870
2.86k
  TIProperty.RawString = Name;
871
2.86k
  TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
872
2.86k
  if (TIProperty.Kind != TraitProperty::invalid) {
873
2.85k
    if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
874
6
      TIProperty.Kind = TraitProperty::invalid;
875
2.85k
    return;
876
2.85k
  }
877
14
878
  // It follows diagnosis and helping notes.
879
  // FIXME: We should move the diagnosis string generation into libFrontend.
880
14
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
881
14
      << Name << getOpenMPContextTraitSelectorName(Selector)
882
14
      << getOpenMPContextTraitSetName(Set);
883
14
884
14
  TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
885
14
  if (SetForName != TraitSet::invalid) {
886
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
887
0
        << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
888
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
889
0
        << Name << "<selector-name>"
890
0
        << "(<property-name>)";
891
0
    return;
892
0
  }
893
14
  TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
894
14
  if (SelectorForName != TraitSelector::invalid) {
895
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
896
0
        << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
897
0
    bool AllowsTraitScore = false;
898
0
    bool RequiresProperty = false;
899
0
    isValidTraitSelectorForTraitSet(
900
0
        SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
901
0
        AllowsTraitScore, RequiresProperty);
902
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
903
0
        << getOpenMPContextTraitSetName(
904
0
               getOpenMPContextTraitSetForSelector(SelectorForName))
905
0
        << Name << (RequiresProperty ? "(<property-name>)" : "");
906
0
    return;
907
0
  }
908
14
  for (const auto &PotentialSet :
909
14
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
910
48
        TraitSet::device}) {
911
48
    TraitProperty PropertyForName =
912
48
        getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
913
48
    if (PropertyForName == TraitProperty::invalid)
914
40
      continue;
915
8
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
916
8
        << getOpenMPContextTraitSetName(
917
8
               getOpenMPContextTraitSetForProperty(PropertyForName))
918
8
        << getOpenMPContextTraitSelectorName(
919
8
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
920
8
        << ("(" + Name + ")").str();
921
8
    return;
922
8
  }
923
6
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
924
6
      << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
925
6
}
926
927
static bool checkExtensionProperty(Parser &P, SourceLocation Loc,
928
                                   OMPTraitProperty &TIProperty,
929
                                   OMPTraitSelector &TISelector,
930
112
                                   llvm::StringMap<SourceLocation> &Seen) {
931
112
  assert(TISelector.Kind ==
932
112
             llvm::omp::TraitSelector::implementation_extension &&
933
112
         "Only for extension properties, e.g., "
934
112
         "`implementation={extension(PROPERTY)}`");
935
112
  if (TIProperty.Kind == TraitProperty::invalid)
936
4
    return false;
937
108
938
112
  
auto IsMatchExtension = [](OMPTraitProperty &TP) 108
{
939
112
    return (TP.Kind ==
940
112
                llvm::omp::TraitProperty::implementation_extension_match_all ||
941
102
            TP.Kind ==
942
102
                llvm::omp::TraitProperty::implementation_extension_match_any ||
943
22
            TP.Kind ==
944
22
                llvm::omp::TraitProperty::implementation_extension_match_none);
945
112
  };
946
108
947
108
  if (IsMatchExtension(TIProperty)) {
948
108
    for (OMPTraitProperty &SeenProp : TISelector.Properties)
949
4
      if (IsMatchExtension(SeenProp)) {
950
4
        P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
951
4
        StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
952
4
            SeenProp.Kind, SeenProp.RawString);
953
4
        SourceLocation SeenLoc = Seen[SeenName];
954
4
        P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
955
4
            << CONTEXT_TRAIT_LVL << SeenName;
956
4
        return false;
957
4
      }
958
104
    return true;
959
0
  }
960
0
961
0
  llvm_unreachable("Unknown extension property!");
962
0
}
963
964
void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
965
                                     llvm::omp::TraitSet Set,
966
2.92k
                                     llvm::StringMap<SourceLocation> &Seen) {
967
2.92k
  assert(TISelector.Kind != TraitSelector::user_condition &&
968
2.92k
         "User conditions are special properties not handled here!");
969
2.92k
970
2.92k
  SourceLocation PropertyLoc = Tok.getLocation();
971
2.92k
  OMPTraitProperty TIProperty;
972
2.92k
  parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
973
2.92k
974
2.92k
  if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
975
112
    if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
976
112
                                TISelector, Seen))
977
8
      TIProperty.Kind = TraitProperty::invalid;
978
2.92k
979
  // If we have an invalid property here we already issued a warning.
980
2.92k
  if (TIProperty.Kind == TraitProperty::invalid) {
981
84
    if (PropertyLoc != Tok.getLocation())
982
24
      Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
983
24
          << CONTEXT_TRAIT_LVL;
984
84
    return;
985
84
  }
986
2.84k
987
2.84k
  if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
988
2.84k
                                                 TISelector.Kind, Set)) {
989
2.84k
990
    // If we make it here the property, selector, set, score, condition, ... are
991
    // all valid (or have been corrected). Thus we can record the property.
992
2.84k
    TISelector.Properties.push_back(TIProperty);
993
2.84k
    return;
994
2.84k
  }
995
0
996
0
  Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
997
0
      << getOpenMPContextTraitPropertyName(TIProperty.Kind,
998
0
                                           TIProperty.RawString)
999
0
      << getOpenMPContextTraitSelectorName(TISelector.Kind)
1000
0
      << getOpenMPContextTraitSetName(Set);
1001
0
  Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1002
0
      << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1003
0
                                           TIProperty.RawString)
1004
0
      << getOpenMPContextTraitSelectorName(
1005
0
             getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1006
0
      << getOpenMPContextTraitSetName(
1007
0
             getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1008
0
  Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1009
0
      << CONTEXT_TRAIT_LVL;
1010
0
}
1011
1012
void Parser::parseOMPTraitSelectorKind(
1013
    OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1014
2.13k
    llvm::StringMap<SourceLocation> &Seen) {
1015
2.13k
  TISelector.Kind = TraitSelector::invalid;
1016
2.13k
1017
2.13k
  SourceLocation NameLoc = Tok.getLocation();
1018
2.13k
  StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL
1019
2.13k
                    );
1020
2.13k
  if (Name.empty()) {
1021
48
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1022
48
        << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1023
48
    return;
1024
48
  }
1025
2.08k
1026
2.08k
  TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1027
2.08k
  if (TISelector.Kind != TraitSelector::invalid) {
1028
2.03k
    if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1029
16
      TISelector.Kind = TraitSelector::invalid;
1030
2.03k
    return;
1031
2.03k
  }
1032
48
1033
  // It follows diagnosis and helping notes.
1034
48
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1035
48
      << Name << getOpenMPContextTraitSetName(Set);
1036
48
1037
48
  TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1038
48
  if (SetForName != TraitSet::invalid) {
1039
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1040
0
        << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1041
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1042
0
        << Name << "<selector-name>"
1043
0
        << "<property-name>";
1044
0
    return;
1045
0
  }
1046
48
  for (const auto &PotentialSet :
1047
48
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1048
192
        TraitSet::device}) {
1049
192
    TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1050
192
        PotentialSet, TraitSelector::invalid, Name);
1051
192
    if (PropertyForName == TraitProperty::invalid)
1052
192
      continue;
1053
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1054
0
        << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1055
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1056
0
        << getOpenMPContextTraitSetName(
1057
0
               getOpenMPContextTraitSetForProperty(PropertyForName))
1058
0
        << getOpenMPContextTraitSelectorName(
1059
0
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
1060
0
        << ("(" + Name + ")").str();
1061
0
    return;
1062
0
  }
1063
48
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1064
48
      << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1065
48
}
1066
1067
/// Parse optional 'score' '(' <expr> ')' ':'.
1068
1.93k
static ExprResult parseContextScore(Parser &P) {
1069
1.93k
  ExprResult ScoreExpr;
1070
1.93k
  llvm::SmallString<16> Buffer;
1071
1.93k
  StringRef SelectorName =
1072
1.93k
      P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1073
1.93k
  if (!SelectorName.equals("score"))
1074
1.70k
    return ScoreExpr;
1075
230
  (void)P.ConsumeToken();
1076
230
  SourceLocation RLoc;
1077
230
  ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1078
  // Parse ':'
1079
230
  if (P.getCurToken().is(tok::colon))
1080
166
    (void)P.ConsumeAnyToken();
1081
64
  else
1082
64
    P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1083
64
        << "':'"
1084
64
        << "score expression";
1085
230
  return ScoreExpr;
1086
230
}
1087
1088
/// Parses an OpenMP context selector.
1089
///
1090
/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1091
void Parser::parseOMPContextSelector(
1092
    OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1093
2.13k
    llvm::StringMap<SourceLocation> &SeenSelectors) {
1094
2.13k
  unsigned short OuterPC = ParenCount;
1095
2.13k
1096
  // If anything went wrong we issue an error or warning and then skip the rest
1097
  // of the selector. However, commas are ambiguous so we look for the nesting
1098
  // of parentheses here as well.
1099
156
  auto FinishSelector = [OuterPC, this]() -> void {
1100
156
    bool Done = false;
1101
156
    while (!Done) {
1102
156
      while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1103
156
                         tok::annot_pragma_openmp_end},
1104
156
                        StopBeforeMatch))
1105
0
        ;
1106
156
      if (Tok.is(tok::r_paren) && 
OuterPC > ParenCount14
)
1107
0
        (void)ConsumeParen();
1108
156
      if (OuterPC <= ParenCount) {
1109
156
        Done = true;
1110
156
        break;
1111
156
      }
1112
0
      if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1113
0
        Done = true;
1114
0
        break;
1115
0
      }
1116
0
      (void)ConsumeAnyToken();
1117
0
    }
1118
156
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1119
156
        << CONTEXT_SELECTOR_LVL;
1120
156
  };
1121
2.13k
1122
2.13k
  SourceLocation SelectorLoc = Tok.getLocation();
1123
2.13k
  parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1124
2.13k
  if (TISelector.Kind == TraitSelector::invalid)
1125
112
    return FinishSelector();
1126
2.02k
1127
2.02k
  bool AllowsTraitScore = false;
1128
2.02k
  bool RequiresProperty = false;
1129
2.02k
  if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1130
16
                                       RequiresProperty)) {
1131
16
    Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1132
16
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1133
16
        << getOpenMPContextTraitSetName(Set);
1134
16
    Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1135
16
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1136
16
        << getOpenMPContextTraitSetName(
1137
16
               getOpenMPContextTraitSetForSelector(TISelector.Kind))
1138
16
        << RequiresProperty;
1139
16
    return FinishSelector();
1140
16
  }
1141
2.00k
1142
2.00k
  if (!RequiresProperty) {
1143
0
    TISelector.Properties.push_back(
1144
0
        {getOpenMPContextTraitPropertyForSelector(TISelector.Kind),
1145
0
         getOpenMPContextTraitSelectorName(TISelector.Kind)});
1146
0
    return;
1147
0
  }
1148
2.00k
1149
2.00k
  if (!Tok.is(tok::l_paren)) {
1150
14
    Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1151
14
        << getOpenMPContextTraitSelectorName(TISelector.Kind)
1152
14
        << getOpenMPContextTraitSetName(Set);
1153
14
    return FinishSelector();
1154
14
  }
1155
1.99k
1156
1.99k
  if (TISelector.Kind == TraitSelector::user_condition) {
1157
54
    SourceLocation RLoc;
1158
54
    ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1159
54
    if (!Condition.isUsable())
1160
14
      return FinishSelector();
1161
40
    TISelector.ScoreOrCondition = Condition.get();
1162
40
    TISelector.Properties.push_back(
1163
40
        {TraitProperty::user_condition_unknown, "<condition>"});
1164
40
    return;
1165
40
  }
1166
1.93k
1167
1.93k
  BalancedDelimiterTracker BDT(*this, tok::l_paren,
1168
1.93k
                               tok::annot_pragma_openmp_end);
1169
  // Parse '('.
1170
1.93k
  (void)BDT.consumeOpen();
1171
1.93k
1172
1.93k
  SourceLocation ScoreLoc = Tok.getLocation();
1173
1.93k
  ExprResult Score = parseContextScore(*this);
1174
1.93k
1175
1.93k
  if (!AllowsTraitScore && 
!Score.isUnset()1.40k
) {
1176
64
    if (Score.isUsable()) {
1177
50
      Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1178
50
          << getOpenMPContextTraitSelectorName(TISelector.Kind)
1179
50
          << getOpenMPContextTraitSetName(Set) << Score.get();
1180
14
    } else {
1181
14
      Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1182
14
          << getOpenMPContextTraitSelectorName(TISelector.Kind)
1183
14
          << getOpenMPContextTraitSetName(Set) << "<invalid>";
1184
14
    }
1185
64
    Score = ExprResult();
1186
64
  }
1187
1.93k
1188
1.93k
  if (Score.isUsable())
1189
144
    TISelector.ScoreOrCondition = Score.get();
1190
1.93k
1191
1.93k
  llvm::StringMap<SourceLocation> SeenProperties;
1192
2.92k
  do {
1193
2.92k
    parseOMPContextProperty(TISelector, Set, SeenProperties);
1194
2.92k
  } while (TryConsumeToken(tok::comma));
1195
1.93k
1196
  // Parse ')'.
1197
1.93k
  BDT.consumeClose();
1198
1.93k
}
1199
1200
void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1201
2.20k
                                  llvm::StringMap<SourceLocation> &Seen) {
1202
2.20k
  TISet.Kind = TraitSet::invalid;
1203
2.20k
1204
2.20k
  SourceLocation NameLoc = Tok.getLocation();
1205
2.20k
  StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL
1206
2.20k
                   );
1207
2.20k
  if (Name.empty()) {
1208
16
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1209
16
        << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1210
16
    return;
1211
16
  }
1212
2.19k
1213
2.19k
  TISet.Kind = getOpenMPContextTraitSetKind(Name);
1214
2.19k
  if (TISet.Kind != TraitSet::invalid) {
1215
2.08k
    if (checkForDuplicates(*this, Name, NameLoc, Seen,
1216
2.08k
                           CONTEXT_SELECTOR_SET_LVL))
1217
0
      TISet.Kind = TraitSet::invalid;
1218
2.08k
    return;
1219
2.08k
  }
1220
110
1221
  // It follows diagnosis and helping notes.
1222
110
  Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1223
110
1224
110
  TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1225
110
  if (SelectorForName != TraitSelector::invalid) {
1226
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1227
0
        << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1228
0
    bool AllowsTraitScore = false;
1229
0
    bool RequiresProperty = false;
1230
0
    isValidTraitSelectorForTraitSet(
1231
0
        SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1232
0
        AllowsTraitScore, RequiresProperty);
1233
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1234
0
        << getOpenMPContextTraitSetName(
1235
0
               getOpenMPContextTraitSetForSelector(SelectorForName))
1236
0
        << Name << (RequiresProperty ? "(<property-name>)" : "");
1237
0
    return;
1238
0
  }
1239
110
  for (const auto &PotentialSet :
1240
110
       {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1241
440
        TraitSet::device}) {
1242
440
    TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1243
440
        PotentialSet, TraitSelector::invalid, Name);
1244
440
    if (PropertyForName == TraitProperty::invalid)
1245
440
      continue;
1246
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1247
0
        << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1248
0
    Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1249
0
        << getOpenMPContextTraitSetName(
1250
0
               getOpenMPContextTraitSetForProperty(PropertyForName))
1251
0
        << getOpenMPContextTraitSelectorName(
1252
0
               getOpenMPContextTraitSelectorForProperty(PropertyForName))
1253
0
        << ("(" + Name + ")").str();
1254
0
    return;
1255
0
  }
1256
110
  Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1257
110
      << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1258
110
}
1259
1260
/// Parses an OpenMP context selector set.
1261
///
1262
/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1263
void Parser::parseOMPContextSelectorSet(
1264
    OMPTraitSet &TISet,
1265
2.20k
    llvm::StringMap<SourceLocation> &SeenSets) {
1266
2.20k
  auto OuterBC = BraceCount;
1267
2.20k
1268
  // If anything went wrong we issue an error or warning and then skip the rest
1269
  // of the set. However, commas are ambiguous so we look for the nesting
1270
  // of braces here as well.
1271
126
  auto FinishSelectorSet = [this, OuterBC]() -> void {
1272
126
    bool Done = false;
1273
126
    while (!Done) {
1274
126
      while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1275
126
                         tok::annot_pragma_openmp_end},
1276
126
                        StopBeforeMatch))
1277
0
        ;
1278
126
      if (Tok.is(tok::r_brace) && 
OuterBC > BraceCount4
)
1279
0
        (void)ConsumeBrace();
1280
126
      if (OuterBC <= BraceCount) {
1281
126
        Done = true;
1282
126
        break;
1283
126
      }
1284
0
      if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1285
0
        Done = true;
1286
0
        break;
1287
0
      }
1288
0
      (void)ConsumeAnyToken();
1289
0
    }
1290
126
    Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1291
126
        << CONTEXT_SELECTOR_SET_LVL;
1292
126
  };
1293
2.20k
1294
2.20k
  parseOMPTraitSetKind(TISet, SeenSets);
1295
2.20k
  if (TISet.Kind == TraitSet::invalid)
1296
126
    return FinishSelectorSet();
1297
2.08k
1298
  // Parse '='.
1299
2.08k
  if (!TryConsumeToken(tok::equal))
1300
4
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1301
4
        << "="
1302
4
        << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1303
4
            "\"")
1304
4
               .str();
1305
2.08k
1306
  // Parse '{'.
1307
2.08k
  if (Tok.is(tok::l_brace)) {
1308
2.07k
    (void)ConsumeBrace();
1309
12
  } else {
1310
12
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1311
12
        << "{"
1312
12
        << ("'=' that follows the context set name \"" +
1313
12
            getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1314
12
               .str();
1315
12
  }
1316
2.08k
1317
2.08k
  llvm::StringMap<SourceLocation> SeenSelectors;
1318
2.13k
  do {
1319
2.13k
    OMPTraitSelector TISelector;
1320
2.13k
    parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1321
2.13k
    if (TISelector.Kind != TraitSelector::invalid &&
1322
2.02k
        !TISelector.Properties.empty())
1323
1.90k
      TISet.Selectors.push_back(TISelector);
1324
2.13k
  } while (TryConsumeToken(tok::comma));
1325
2.08k
1326
  // Parse '}'.
1327
2.08k
  if (Tok.is(tok::r_brace)) {
1328
2.06k
    (void)ConsumeBrace();
1329
16
  } else {
1330
16
    Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1331
16
        << "}"
1332
16
        << ("context selectors for the context set \"" +
1333
16
            getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1334
16
               .str();
1335
16
  }
1336
2.08k
}
1337
1338
/// Parse OpenMP context selectors:
1339
///
1340
/// <trait-set-selector> [, <trait-set-selector>]*
1341
1.97k
bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo& TI) {
1342
1.97k
  llvm::StringMap<SourceLocation> SeenSets;
1343
2.20k
  do {
1344
2.20k
    OMPTraitSet TISet;
1345
2.20k
    parseOMPContextSelectorSet(TISet, SeenSets);
1346
2.20k
    if (TISet.Kind != TraitSet::invalid && 
!TISet.Selectors.empty()2.08k
)
1347
1.89k
      TI.Sets.push_back(TISet);
1348
2.20k
  } while (TryConsumeToken(tok::comma));
1349
1.97k
1350
1.97k
  return false;
1351
1.97k
}
1352
1353
/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
1354
void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1355
                                           CachedTokens &Toks,
1356
1.79k
                                           SourceLocation Loc) {
1357
1.79k
  PP.EnterToken(Tok, /*IsReinject*/ true);
1358
1.79k
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1359
1.79k
                      /*IsReinject*/ true);
1360
  // Consume the previously pushed token.
1361
1.79k
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1362
1.79k
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1363
1.79k
1364
1.79k
  FNContextRAII FnContext(*this, Ptr);
1365
  // Parse function declaration id.
1366
1.79k
  SourceLocation RLoc;
1367
  // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1368
  // instead of MemberExprs.
1369
1.79k
  ExprResult AssociatedFunction;
1370
1.79k
  {
1371
    // Do not mark function as is used to prevent its emission if this is the
1372
    // only place where it is used.
1373
1.79k
    EnterExpressionEvaluationContext Unevaluated(
1374
1.79k
        Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1375
1.79k
    AssociatedFunction = ParseOpenMPParensExpr(
1376
1.79k
        getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1377
1.79k
        /*IsAddressOfOperand=*/true);
1378
1.79k
  }
1379
1.79k
  if (!AssociatedFunction.isUsable()) {
1380
16
    if (!Tok.is(tok::annot_pragma_openmp_end))
1381
2
      while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1382
0
        ;
1383
    // Skip the last annot_pragma_openmp_end.
1384
16
    (void)ConsumeAnnotationToken();
1385
16
    return;
1386
16
  }
1387
1.77k
1388
1.77k
  OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
1389
1.77k
  if (parseOMPDeclareVariantMatchClause(Loc, TI))
1390
36
    return;
1391
1.74k
1392
1.74k
  Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1393
1.74k
      Actions.checkOpenMPDeclareVariantFunction(
1394
1.74k
          Ptr, AssociatedFunction.get(), TI,
1395
1.74k
          SourceRange(Loc, Tok.getLocation()));
1396
1.74k
1397
  // Skip last tokens.
1398
1.75k
  while (Tok.isNot(tok::annot_pragma_openmp_end))
1399
10
    ConsumeAnyToken();
1400
1.74k
  if (DeclVarData && 
!TI.Sets.empty()1.67k
)
1401
1.46k
    Actions.ActOnOpenMPDeclareVariantDirective(
1402
1.46k
        DeclVarData->first, DeclVarData->second, TI,
1403
1.46k
        SourceRange(Loc, Tok.getLocation()));
1404
1.74k
1405
  // Skip the last annot_pragma_openmp_end.
1406
1.74k
  (void)ConsumeAnnotationToken();
1407
1.74k
}
1408
1409
bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1410
2.01k
                                               OMPTraitInfo &TI) {
1411
  // Parse 'match'.
1412
2.01k
  OpenMPClauseKind CKind = Tok.isAnnotation()
1413
28
                               ? OMPC_unknown
1414
1.98k
                               : getOpenMPClauseKind(PP.getSpelling(Tok));
1415
2.01k
  if (CKind != OMPC_match) {
1416
36
    Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1417
36
        << getOpenMPClauseName(OMPC_match);
1418
36
    while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1419
0
      ;
1420
    // Skip the last annot_pragma_openmp_end.
1421
36
    (void)ConsumeAnnotationToken();
1422
36
    return true;
1423
36
  }
1424
1.97k
  (void)ConsumeToken();
1425
  // Parse '('.
1426
1.97k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1427
1.97k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1428
8
                         getOpenMPClauseName(OMPC_match).data())) {
1429
8
    while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1430
0
      ;
1431
    // Skip the last annot_pragma_openmp_end.
1432
8
    (void)ConsumeAnnotationToken();
1433
8
    return true;
1434
8
  }
1435
1.97k
1436
  // Parse inner context selectors.
1437
1.97k
  parseOMPContextSelectors(Loc, TI);
1438
1.97k
1439
  // Parse ')'
1440
1.97k
  (void)T.consumeClose();
1441
1.97k
  return false;
1442
1.97k
}
1443
1444
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1445
///
1446
///    default-clause:
1447
///         'default' '(' 'none' | 'shared'  | 'firstprivate' ')
1448
///
1449
///    proc_bind-clause:
1450
///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1451
///
1452
///    device_type-clause:
1453
///         'device_type' '(' 'host' | 'nohost' | 'any' )'
1454
namespace {
1455
  struct SimpleClauseData {
1456
    unsigned Type;
1457
    SourceLocation Loc;
1458
    SourceLocation LOpen;
1459
    SourceLocation TypeLoc;
1460
    SourceLocation RLoc;
1461
    SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1462
                     SourceLocation TypeLoc, SourceLocation RLoc)
1463
2.82k
        : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1464
  };
1465
} // anonymous namespace
1466
1467
static Optional<SimpleClauseData>
1468
3.03k
parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1469
3.03k
  const Token &Tok = P.getCurToken();
1470
3.03k
  SourceLocation Loc = Tok.getLocation();
1471
3.03k
  SourceLocation LOpen = P.ConsumeToken();
1472
  // Parse '('.
1473
3.03k
  BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1474
3.03k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1475
3.03k
                         getOpenMPClauseName(Kind).data()))
1476
203
    return llvm::None;
1477
2.82k
1478
2.82k
  unsigned Type = getOpenMPSimpleClauseType(
1479
2.62k
      Kind, Tok.isAnnotation() ? 
""203
: P.getPreprocessor().getSpelling(Tok),
1480
2.82k
      P.getLangOpts().OpenMP);
1481
2.82k
  SourceLocation TypeLoc = Tok.getLocation();
1482
2.82k
  if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)2.69k
&&
1483
2.69k
      Tok.isNot(tok::annot_pragma_openmp_end))
1484
2.49k
    P.ConsumeAnyToken();
1485
2.82k
1486
  // Parse ')'.
1487
2.82k
  SourceLocation RLoc = Tok.getLocation();
1488
2.82k
  if (!T.consumeClose())
1489
2.34k
    RLoc = T.getCloseLocation();
1490
2.82k
1491
2.82k
  return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1492
2.82k
}
1493
1494
296
Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
1495
  // OpenMP 4.5 syntax with list of entities.
1496
296
  Sema::NamedDeclSetType SameDirectiveDecls;
1497
296
  SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation,
1498
296
                         NamedDecl *>,
1499
296
              4>
1500
296
      DeclareTargetDecls;
1501
296
  OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any;
1502
296
  SourceLocation DeviceTypeLoc;
1503
684
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1504
416
    OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1505
416
    if (Tok.is(tok::identifier)) {
1506
355
      IdentifierInfo *II = Tok.getIdentifierInfo();
1507
355
      StringRef ClauseName = II->getName();
1508
355
      bool IsDeviceTypeClause =
1509
355
          getLangOpts().OpenMP >= 50 &&
1510
301
          getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1511
      // Parse 'to|link|device_type' clauses.
1512
355
      if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) &&
1513
96
          !IsDeviceTypeClause) {
1514
22
        Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1515
14
            << ClauseName << (getLangOpts().OpenMP >= 50 ? 
18
: 0);
1516
22
        break;
1517
22
      }
1518
      // Parse 'device_type' clause and go to next clause if any.
1519
333
      if (IsDeviceTypeClause) {
1520
74
        Optional<SimpleClauseData> DevTypeData =
1521
74
            parseOpenMPSimpleClause(*this, OMPC_device_type);
1522
74
        if (DevTypeData.hasValue()) {
1523
74
          if (DeviceTypeLoc.isValid()) {
1524
            // We already saw another device_type clause, diagnose it.
1525
8
            Diag(DevTypeData.getValue().Loc,
1526
8
                 diag::warn_omp_more_one_device_type_clause);
1527
8
          }
1528
74
          switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1529
12
          case OMPC_DEVICE_TYPE_any:
1530
12
            DT = OMPDeclareTargetDeclAttr::DT_Any;
1531
12
            break;
1532
22
          case OMPC_DEVICE_TYPE_host:
1533
22
            DT = OMPDeclareTargetDeclAttr::DT_Host;
1534
22
            break;
1535
40
          case OMPC_DEVICE_TYPE_nohost:
1536
40
            DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1537
40
            break;
1538
0
          case OMPC_DEVICE_TYPE_unknown:
1539
0
            llvm_unreachable("Unexpected device_type");
1540
74
          }
1541
74
          DeviceTypeLoc = DevTypeData.getValue().Loc;
1542
74
        }
1543
74
        continue;
1544
259
      }
1545
259
      ConsumeToken();
1546
259
    }
1547
320
    auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls](
1548
371
                          CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
1549
371
      NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName(
1550
371
          getCurScope(), SS, NameInfo, SameDirectiveDecls);
1551
371
      if (ND)
1552
353
        DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND);
1553
371
    };
1554
320
    if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1555
320
                                 /*AllowScopeSpecifier=*/true))
1556
6
      break;
1557
314
1558
    // Consume optional ','.
1559
314
    if (Tok.is(tok::comma))
1560
12
      ConsumeToken();
1561
314
  }
1562
296
  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1563
296
  ConsumeAnyToken();
1564
353
  for (auto &MTLocDecl : DeclareTargetDecls) {
1565
353
    OMPDeclareTargetDeclAttr::MapTypeTy MT;
1566
353
    SourceLocation Loc;
1567
353
    NamedDecl *ND;
1568
353
    std::tie(MT, Loc, ND) = MTLocDecl;
1569
    // device_type clause is applied only to functions.
1570
353
    Actions.ActOnOpenMPDeclareTargetName(
1571
215
        ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : 
DT138
);
1572
353
  }
1573
296
  SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
1574
296
                               SameDirectiveDecls.end());
1575
296
  if (Decls.empty())
1576
30
    return DeclGroupPtrTy();
1577
266
  return Actions.BuildDeclaratorGroup(Decls);
1578
266
}
1579
1580
7.75k
void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1581
  // The last seen token is annot_pragma_openmp_end - need to check for
1582
  // extra tokens.
1583
7.75k
  if (Tok.is(tok::annot_pragma_openmp_end))
1584
4.27k
    return;
1585
3.48k
1586
3.48k
  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1587
3.48k
      << getOpenMPDirectiveName(DKind);
1588
8.20k
  while (Tok.isNot(tok::annot_pragma_openmp_end))
1589
4.72k
    ConsumeAnyToken();
1590
3.48k
}
1591
1592
void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1593
                                  OpenMPDirectiveKind ExpectedKind,
1594
                                  OpenMPDirectiveKind FoundKind,
1595
                                  SourceLocation BeginLoc,
1596
                                  SourceLocation FoundLoc,
1597
459
                                  bool SkipUntilOpenMPEnd) {
1598
438
  int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 
121
;
1599
459
1600
459
  if (FoundKind == ExpectedKind) {
1601
441
    ConsumeAnyToken();
1602
441
    skipUntilPragmaOpenMPEnd(ExpectedKind);
1603
441
    return;
1604
441
  }
1605
18
1606
18
  Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1607
18
      << DiagSelection;
1608
18
  Diag(BeginLoc, diag::note_matching)
1609
18
      << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1610
18
  if (SkipUntilOpenMPEnd)
1611
6
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1612
18
}
1613
1614
void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
1615
438
                                               SourceLocation DKLoc) {
1616
438
  parseOMPEndDirective(OMPD_declare_target, OMPD_end_declare_target, DKind,
1617
438
                       DKLoc, Tok.getLocation(),
1618
438
                       /* SkipUntilOpenMPEnd */ false);
1619
  // Skip the last annot_pragma_openmp_end.
1620
438
  if (Tok.is(tok::annot_pragma_openmp_end))
1621
426
    ConsumeAnnotationToken();
1622
438
}
1623
1624
/// Parsing of declarative OpenMP directives.
1625
///
1626
///       threadprivate-directive:
1627
///         annot_pragma_openmp 'threadprivate' simple-variable-list
1628
///         annot_pragma_openmp_end
1629
///
1630
///       allocate-directive:
1631
///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1632
///         annot_pragma_openmp_end
1633
///
1634
///       declare-reduction-directive:
1635
///        annot_pragma_openmp 'declare' 'reduction' [...]
1636
///        annot_pragma_openmp_end
1637
///
1638
///       declare-mapper-directive:
1639
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1640
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1641
///         annot_pragma_openmp_end
1642
///
1643
///       declare-simd-directive:
1644
///         annot_pragma_openmp 'declare simd' {<clause> [,]}
1645
///         annot_pragma_openmp_end
1646
///         <function declaration/definition>
1647
///
1648
///       requires directive:
1649
///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1650
///         annot_pragma_openmp_end
1651
///
1652
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
1653
    AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
1654
7.50k
    DeclSpec::TST TagType, Decl *Tag) {
1655
7.50k
  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1656
7.50k
  ParsingOpenMPDirectiveRAII DirScope(*this);
1657
7.50k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1658
7.50k
1659
7.50k
  SourceLocation Loc;
1660
7.50k
  OpenMPDirectiveKind DKind;
1661
7.50k
  if (Delayed) {
1662
659
    TentativeParsingAction TPA(*this);
1663
659
    Loc = ConsumeAnnotationToken();
1664
659
    DKind = parseOpenMPDirectiveKind(*this);
1665
659
    if (DKind == OMPD_declare_reduction || 
DKind == OMPD_declare_mapper599
) {
1666
      // Need to delay parsing until completion of the parent class.
1667
86
      TPA.Revert();
1668
86
      CachedTokens Toks;
1669
86
      unsigned Cnt = 1;
1670
86
      Toks.push_back(Tok);
1671
1.41k
      while (Cnt && 
Tok.isNot(tok::eof)1.33k
) {
1672
1.33k
        (void)ConsumeAnyToken();
1673
1.33k
        if (Tok.is(tok::annot_pragma_openmp))
1674
0
          ++Cnt;
1675
1.33k
        else if (Tok.is(tok::annot_pragma_openmp_end))
1676
86
          --Cnt;
1677
1.33k
        Toks.push_back(Tok);
1678
1.33k
      }
1679
      // Skip last annot_pragma_openmp_end.
1680
86
      if (Cnt == 0)
1681
86
        (void)ConsumeAnyToken();
1682
86
      auto *LP = new LateParsedPragma(this, AS);
1683
86
      LP->takeToks(Toks);
1684
86
      getCurrentClass().LateParsedDeclarations.push_back(LP);
1685
86
      return nullptr;
1686
86
    }
1687
573
    TPA.Commit();
1688
6.84k
  } else {
1689
6.84k
    Loc = ConsumeAnnotationToken();
1690
6.84k
    DKind = parseOpenMPDirectiveKind(*this);
1691
6.84k
  }
1692
7.50k
1693
7.41k
  switch (DKind) {
1694
2.26k
  case OMPD_threadprivate: {
1695
2.26k
    ConsumeToken();
1696
2.26k
    DeclDirectiveListParserHelper Helper(this, DKind);
1697
2.26k
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1698
2.22k
                                  /*AllowScopeSpecifier=*/true)) {
1699
2.22k
      skipUntilPragmaOpenMPEnd(DKind);
1700
      // Skip the last annot_pragma_openmp_end.
1701
2.22k
      ConsumeAnnotationToken();
1702
2.22k
      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1703
2.22k
                                                       Helper.getIdentifiers());
1704
2.22k
    }
1705
40
    break;
1706
40
  }
1707
392
  case OMPD_allocate: {
1708
392
    ConsumeToken();
1709
392
    DeclDirectiveListParserHelper Helper(this, DKind);
1710
392
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1711
352
                                  /*AllowScopeSpecifier=*/true)) {
1712
352
      SmallVector<OMPClause *, 1> Clauses;
1713
352
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1714
196
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1715
196
                    llvm::omp::Clause_enumSize + 1>
1716
196
            FirstClauses(llvm::omp::Clause_enumSize + 1);
1717
196
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1718
196
          OpenMPClauseKind CKind =
1719
0
              Tok.isAnnotation() ? OMPC_unknown
1720
196
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
1721
196
          Actions.StartOpenMPClause(CKind);
1722
196
          OMPClause *Clause = ParseOpenMPClause(
1723
196
              OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
1724
196
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1725
196
                    StopBeforeMatch);
1726
196
          FirstClauses[unsigned(CKind)].setInt(true);
1727
196
          if (Clause != nullptr)
1728
144
            Clauses.push_back(Clause);
1729
196
          if (Tok.is(tok::annot_pragma_openmp_end)) {
1730
196
            Actions.EndOpenMPClause();
1731
196
            break;
1732
196
          }
1733
          // Skip ',' if any.
1734
0
          if (Tok.is(tok::comma))
1735
0
            ConsumeToken();
1736
0
          Actions.EndOpenMPClause();
1737
0
        }
1738
196
        skipUntilPragmaOpenMPEnd(DKind);
1739
196
      }
1740
      // Skip the last annot_pragma_openmp_end.
1741
352
      ConsumeAnnotationToken();
1742
352
      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1743
352
                                                  Clauses);
1744
352
    }
1745
40
    break;
1746
40
  }
1747
180
  case OMPD_requires: {
1748
180
    SourceLocation StartLoc = ConsumeToken();
1749
180
    SmallVector<OMPClause *, 5> Clauses;
1750
180
    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1751
180
                llvm::omp::Clause_enumSize + 1>
1752
180
        FirstClauses(llvm::omp::Clause_enumSize + 1);
1753
180
    if (Tok.is(tok::annot_pragma_openmp_end)) {
1754
1
      Diag(Tok, diag::err_omp_expected_clause)
1755
1
          << getOpenMPDirectiveName(OMPD_requires);
1756
1
      break;
1757
1
    }
1758
190
    
while (179
Tok.isNot(tok::annot_pragma_openmp_end)) {
1759
190
      OpenMPClauseKind CKind = Tok.isAnnotation()
1760
0
                                   ? OMPC_unknown
1761
190
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
1762
190
      Actions.StartOpenMPClause(CKind);
1763
190
      OMPClause *Clause = ParseOpenMPClause(
1764
190
          OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
1765
190
      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1766
190
                StopBeforeMatch);
1767
190
      FirstClauses[unsigned(CKind)].setInt(true);
1768
190
      if (Clause != nullptr)
1769
175
        Clauses.push_back(Clause);
1770
190
      if (Tok.is(tok::annot_pragma_openmp_end)) {
1771
179
        Actions.EndOpenMPClause();
1772
179
        break;
1773
179
      }
1774
      // Skip ',' if any.
1775
11
      if (Tok.is(tok::comma))
1776
10
        ConsumeToken();
1777
11
      Actions.EndOpenMPClause();
1778
11
    }
1779
    // Consume final annot_pragma_openmp_end
1780
179
    if (Clauses.empty()) {
1781
8
      Diag(Tok, diag::err_omp_expected_clause)
1782
8
          << getOpenMPDirectiveName(OMPD_requires);
1783
8
      ConsumeAnnotationToken();
1784
8
      return nullptr;
1785
8
    }
1786
171
    ConsumeAnnotationToken();
1787
171
    return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1788
171
  }
1789
526
  case OMPD_declare_reduction:
1790
526
    ConsumeToken();
1791
526
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
1792
368
      skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
1793
      // Skip the last annot_pragma_openmp_end.
1794
368
      ConsumeAnnotationToken();
1795
368
      return Res;
1796
368
    }
1797
158
    break;
1798
272
  case OMPD_declare_mapper: {
1799
272
    ConsumeToken();
1800
272
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1801
      // Skip the last annot_pragma_openmp_end.
1802
156
      ConsumeAnnotationToken();
1803
156
      return Res;
1804
156
    }
1805
116
    break;
1806
116
  }
1807
237
  case OMPD_begin_declare_variant: {
1808
    // The syntax is:
1809
    // { #pragma omp begin declare variant clause }
1810
    // <function-declaration-or-definition-sequence>
1811
    // { #pragma omp end declare variant }
1812
    //
1813
237
    ConsumeToken();
1814
237
    OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
1815
237
    if (parseOMPDeclareVariantMatchClause(Loc, TI))
1816
8
      break;
1817
229
1818
    // Skip last tokens.
1819
229
    skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
1820
229
1821
229
    ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
1822
229
1823
229
    VariantMatchInfo VMI;
1824
229
    ASTContext &ASTCtx = Actions.getASTContext();
1825
229
    TI.getAsVariantMatchInfo(ASTCtx, VMI);
1826
229
1827
229
    std::function<void(StringRef)> DiagUnknownTrait = [this, Loc](
1828
0
                                                          StringRef ISATrait) {
1829
      // TODO Track the selector locations in a way that is accessible here to
1830
      // improve the diagnostic location.
1831
0
      Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait;
1832
0
    };
1833
229
    TargetOMPContext OMPCtx(ASTCtx, std::move(DiagUnknownTrait),
1834
229
                            /* CurrentFunctionDecl */ nullptr);
1835
229
1836
229
    if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
1837
208
      Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
1838
208
      break;
1839
208
    }
1840
21
1841
    // Elide all the code till the matching end declare variant was found.
1842
21
    unsigned Nesting = 1;
1843
21
    SourceLocation DKLoc;
1844
21
    OpenMPDirectiveKind DK = OMPD_unknown;
1845
31.5k
    do {
1846
31.5k
      DKLoc = Tok.getLocation();
1847
31.5k
      DK = parseOpenMPDirectiveKind(*this);
1848
31.5k
      if (DK == OMPD_end_declare_variant)
1849
23
        --Nesting;
1850
31.5k
      else if (DK == OMPD_begin_declare_variant)
1851
8
        ++Nesting;
1852
31.5k
      if (!Nesting || 
isEofOrEom()31.5k
)
1853
21
        break;
1854
31.5k
      ConsumeAnyToken();
1855
31.5k
    } while (true);
1856
21
1857
21
    parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
1858
21
                         DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
1859
21
    if (isEofOrEom())
1860
6
      return nullptr;
1861
15
    break;
1862
15
  }
1863
218
  case OMPD_end_declare_variant: {
1864
218
    if (Actions.isInOpenMPDeclareVariantScope())
1865
204
      Actions.ActOnOpenMPEndDeclareVariant();
1866
14
    else
1867
14
      Diag(Loc, diag::err_expected_begin_declare_variant);
1868
218
    ConsumeToken();
1869
218
    break;
1870
15
  }
1871
2.32k
  case OMPD_declare_variant:
1872
2.32k
  case OMPD_declare_simd: {
1873
    // The syntax is:
1874
    // { #pragma omp declare {simd|variant} }
1875
    // <function-declaration-or-definition>
1876
    //
1877
2.32k
    CachedTokens Toks;
1878
2.32k
    Toks.push_back(Tok);
1879
2.32k
    ConsumeToken();
1880
34.7k
    while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1881
32.4k
      Toks.push_back(Tok);
1882
32.4k
      ConsumeAnyToken();
1883
32.4k
    }
1884
2.32k
    Toks.push_back(Tok);
1885
2.32k
    ConsumeAnyToken();
1886
2.32k
1887
2.32k
    DeclGroupPtrTy Ptr;
1888
2.32k
    if (Tok.is(tok::annot_pragma_openmp)) {
1889
880
      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
1890
880
                                                       TagType, Tag);
1891
1.44k
    } else if (Tok.isNot(tok::r_brace) && 
!isEofOrEom()1.44k
) {
1892
      // Here we expect to see some function declaration.
1893
1.43k
      if (AS == AS_none) {
1894
1.08k
        assert(TagType == DeclSpec::TST_unspecified);
1895
1.08k
        MaybeParseCXX11Attributes(Attrs);
1896
1.08k
        ParsingDeclSpec PDS(*this);
1897
1.08k
        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1898
354
      } else {
1899
354
        Ptr =
1900
354
            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1901
354
      }
1902
1.43k
    }
1903
2.32k
    if (!Ptr) {
1904
50
      Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
1905
32
          << (DKind == OMPD_declare_simd ? 
018
: 1);
1906
50
      return DeclGroupPtrTy();
1907
50
    }
1908
2.27k
    if (DKind == OMPD_declare_simd)
1909
482
      return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1910
1.79k
    assert(DKind == OMPD_declare_variant &&
1911
1.79k
           "Expected declare variant directive only");
1912
1.79k
    ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1913
1.79k
    return Ptr;
1914
1.79k
  }
1915
734
  case OMPD_declare_target: {
1916
734
    SourceLocation DTLoc = ConsumeAnyToken();
1917
734
    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1918
296
      return ParseOMPDeclareTargetClauses();
1919
296
    }
1920
438
1921
    // Skip the last annot_pragma_openmp_end.
1922
438
    ConsumeAnyToken();
1923
438
1924
438
    if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1925
0
      return DeclGroupPtrTy();
1926
438
1927
438
    ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
1928
438
    llvm::SmallVector<Decl *, 4>  Decls;
1929
438
    DKind = parseOpenMPDirectiveKind(*this);
1930
3.14k
    while (DKind != OMPD_end_declare_target && 
Tok.isNot(tok::eof)2.72k
&&
1931
2.71k
           Tok.isNot(tok::r_brace)) {
1932
2.71k
      DeclGroupPtrTy Ptr;
1933
      // Here we expect to see some function declaration.
1934
2.71k
      if (AS == AS_none) {
1935
2.68k
        assert(TagType == DeclSpec::TST_unspecified);
1936
2.68k
        MaybeParseCXX11Attributes(Attrs);
1937
2.68k
        ParsingDeclSpec PDS(*this);
1938
2.68k
        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1939
30
      } else {
1940
30
        Ptr =
1941
30
            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1942
30
      }
1943
2.71k
      if (Ptr) {
1944
2.70k
        DeclGroupRef Ref = Ptr.get();
1945
2.70k
        Decls.append(Ref.begin(), Ref.end());
1946
2.70k
      }
1947
2.71k
      if (Tok.isAnnotation() && 
Tok.is(tok::annot_pragma_openmp)1.05k
) {
1948
1.05k
        TentativeParsingAction TPA(*this);
1949
1.05k
        ConsumeAnnotationToken();
1950
1.05k
        DKind = parseOpenMPDirectiveKind(*this);
1951
1.05k
        if (DKind != OMPD_end_declare_target)
1952
625
          TPA.Revert();
1953
426
        else
1954
426
          TPA.Commit();
1955
1.05k
      }
1956
2.71k
    }
1957
438
1958
438
    ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1959
438
    Actions.ActOnFinishOpenMPDeclareTargetDirective();
1960
438
    return Actions.BuildDeclaratorGroup(Decls);
1961
438
  }
1962
24
  case OMPD_unknown:
1963
24
    Diag(Tok, diag::err_omp_unknown_directive);
1964
24
    break;
1965
244
  case OMPD_parallel:
1966
244
  case OMPD_simd:
1967
244
  case OMPD_task:
1968
244
  case OMPD_taskyield:
1969
244
  case OMPD_barrier:
1970
244
  case OMPD_taskwait:
1971
244
  case OMPD_taskgroup:
1972
244
  case OMPD_flush:
1973
244
  case OMPD_depobj:
1974
244
  case OMPD_scan:
1975
244
  case OMPD_for:
1976
244
  case OMPD_for_simd:
1977
244
  case OMPD_sections:
1978
244
  case OMPD_section:
1979
244
  case OMPD_single:
1980
244
  case OMPD_master:
1981
244
  case OMPD_ordered:
1982
244
  case OMPD_critical:
1983
244
  case OMPD_parallel_for:
1984
244
  case OMPD_parallel_for_simd:
1985
244
  case OMPD_parallel_sections:
1986
244
  case OMPD_parallel_master:
1987
244
  case OMPD_atomic:
1988
244
  case OMPD_target:
1989
244
  case OMPD_teams:
1990
244
  case OMPD_cancellation_point:
1991
244
  case OMPD_cancel:
1992
244
  case OMPD_target_data:
1993
244
  case OMPD_target_enter_data:
1994
244
  case OMPD_target_exit_data:
1995
244
  case OMPD_target_parallel:
1996
244
  case OMPD_target_parallel_for:
1997
244
  case OMPD_taskloop:
1998
244
  case OMPD_taskloop_simd:
1999
244
  case OMPD_master_taskloop:
2000
244
  case OMPD_master_taskloop_simd:
2001
244
  case OMPD_parallel_master_taskloop:
2002
244
  case OMPD_parallel_master_taskloop_simd:
2003
244
  case OMPD_distribute:
2004
244
  case OMPD_end_declare_target:
2005
244
  case OMPD_target_update:
2006
244
  case OMPD_distribute_parallel_for:
2007
244
  case OMPD_distribute_parallel_for_simd:
2008
244
  case OMPD_distribute_simd:
2009
244
  case OMPD_target_parallel_for_simd:
2010
244
  case OMPD_target_simd:
2011
244
  case OMPD_teams_distribute:
2012
244
  case OMPD_teams_distribute_simd:
2013
244
  case OMPD_teams_distribute_parallel_for_simd:
2014
244
  case OMPD_teams_distribute_parallel_for:
2015
244
  case OMPD_target_teams:
2016
244
  case OMPD_target_teams_distribute:
2017
244
  case OMPD_target_teams_distribute_parallel_for:
2018
244
  case OMPD_target_teams_distribute_parallel_for_simd:
2019
244
  case OMPD_target_teams_distribute_simd:
2020
244
    Diag(Tok, diag::err_omp_unexpected_directive)
2021
244
        << 1 << getOpenMPDirectiveName(DKind);
2022
244
    break;
2023
0
  default:
2024
0
    break;
2025
1.07k
  }
2026
1.55k
  
while (1.07k
Tok.isNot(tok::annot_pragma_openmp_end))
2027
486
    ConsumeAnyToken();
2028
1.07k
  ConsumeAnyToken();
2029
1.07k
  return nullptr;
2030
1.07k
}
2031
2032
/// Parsing of declarative or executable OpenMP directives.
2033
///
2034
///       threadprivate-directive:
2035
///         annot_pragma_openmp 'threadprivate' simple-variable-list
2036
///         annot_pragma_openmp_end
2037
///
2038
///       allocate-directive:
2039
///         annot_pragma_openmp 'allocate' simple-variable-list
2040
///         annot_pragma_openmp_end
2041
///
2042
///       declare-reduction-directive:
2043
///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2044
///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2045
///         ('omp_priv' '=' <expression>|<function_call>) ')']
2046
///         annot_pragma_openmp_end
2047
///
2048
///       declare-mapper-directive:
2049
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2050
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2051
///         annot_pragma_openmp_end
2052
///
2053
///       executable-directive:
2054
///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2055
///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2056
///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2057
///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2058
///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2059
///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2060
///         'master taskloop' | 'master taskloop simd' | 'parallel master
2061
///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2062
///         enter data' | 'target exit data' | 'target parallel' | 'target
2063
///         parallel for' | 'target update' | 'distribute parallel for' |
2064
///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2065
///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2066
///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2067
///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2068
///         teams distribute parallel for' | 'target teams distribute parallel
2069
///         for simd' | 'target teams distribute simd' {clause}
2070
///         annot_pragma_openmp_end
2071
///
2072
StmtResult
2073
222k
Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2074
222k
  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
2075
222k
  ParsingOpenMPDirectiveRAII DirScope(*this);
2076
222k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
2077
222k
  SmallVector<OMPClause *, 5> Clauses;
2078
222k
  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2079
222k
              llvm::omp::Clause_enumSize + 1>
2080
222k
      FirstClauses(llvm::omp::Clause_enumSize + 1);
2081
222k
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2082
222k
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2083
222k
  SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
2084
222k
  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2085
222k
  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2086
  // Name of critical directive.
2087
222k
  DeclarationNameInfo DirName;
2088
222k
  StmtResult Directive = StmtError();
2089
222k
  bool HasAssociatedStatement = true;
2090
222k
2091
222k
  switch (DKind) {
2092
230
  case OMPD_threadprivate: {
2093
    // FIXME: Should this be permitted in C++?
2094
230
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2095
4
        ParsedStmtContext()) {
2096
4
      Diag(Tok, diag::err_omp_immediate_directive)
2097
4
          << getOpenMPDirectiveName(DKind) << 0;
2098
4
    }
2099
230
    ConsumeToken();
2100
230
    DeclDirectiveListParserHelper Helper(this, DKind);
2101
230
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2102
226
                                  /*AllowScopeSpecifier=*/false)) {
2103
226
      skipUntilPragmaOpenMPEnd(DKind);
2104
226
      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2105
226
          Loc, Helper.getIdentifiers());
2106
226
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2107
226
    }
2108
230
    SkipUntil(tok::annot_pragma_openmp_end);
2109
230
    break;
2110
0
  }
2111
138
  case OMPD_allocate: {
2112
    // FIXME: Should this be permitted in C++?
2113
138
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2114
4
        ParsedStmtContext()) {
2115
4
      Diag(Tok, diag::err_omp_immediate_directive)
2116
4
          << getOpenMPDirectiveName(DKind) << 0;
2117
4
    }
2118
138
    ConsumeToken();
2119
138
    DeclDirectiveListParserHelper Helper(this, DKind);
2120
138
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
2121
134
                                  /*AllowScopeSpecifier=*/false)) {
2122
134
      SmallVector<OMPClause *, 1> Clauses;
2123
134
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2124
60
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2125
60
                    llvm::omp::Clause_enumSize + 1>
2126
60
            FirstClauses(llvm::omp::Clause_enumSize + 1);
2127
60
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2128
60
          OpenMPClauseKind CKind =
2129
0
              Tok.isAnnotation() ? OMPC_unknown
2130
60
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
2131
60
          Actions.StartOpenMPClause(CKind);
2132
60
          OMPClause *Clause = ParseOpenMPClause(
2133
60
              OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2134
60
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2135
60
                    StopBeforeMatch);
2136
60
          FirstClauses[unsigned(CKind)].setInt(true);
2137
60
          if (Clause != nullptr)
2138
56
            Clauses.push_back(Clause);
2139
60
          if (Tok.is(tok::annot_pragma_openmp_end)) {
2140
60
            Actions.EndOpenMPClause();
2141
60
            break;
2142
60
          }
2143
          // Skip ',' if any.
2144
0
          if (Tok.is(tok::comma))
2145
0
            ConsumeToken();
2146
0
          Actions.EndOpenMPClause();
2147
0
        }
2148
60
        skipUntilPragmaOpenMPEnd(DKind);
2149
60
      }
2150
134
      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2151
134
          Loc, Helper.getIdentifiers(), Clauses);
2152
134
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2153
134
    }
2154
138
    SkipUntil(tok::annot_pragma_openmp_end);
2155
138
    break;
2156
0
  }
2157
152
  case OMPD_declare_reduction:
2158
152
    ConsumeToken();
2159
152
    if (DeclGroupPtrTy Res =
2160
152
            ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2161
152
      skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2162
152
      ConsumeAnyToken();
2163
152
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2164
0
    } else {
2165
0
      SkipUntil(tok::annot_pragma_openmp_end);
2166
0
    }
2167
152
    break;
2168
90
  case OMPD_declare_mapper: {
2169
90
    ConsumeToken();
2170
90
    if (DeclGroupPtrTy Res =
2171
88
            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2172
      // Skip the last annot_pragma_openmp_end.
2173
88
      ConsumeAnnotationToken();
2174
88
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2175
2
    } else {
2176
2
      SkipUntil(tok::annot_pragma_openmp_end);
2177
2
    }
2178
90
    break;
2179
0
  }
2180
9.64k
  case OMPD_flush:
2181
9.64k
  case OMPD_depobj:
2182
9.64k
  case OMPD_scan:
2183
9.64k
  case OMPD_taskyield:
2184
9.64k
  case OMPD_barrier:
2185
9.64k
  case OMPD_taskwait:
2186
9.64k
  case OMPD_cancellation_point:
2187
9.64k
  case OMPD_cancel:
2188
9.64k
  case OMPD_target_enter_data:
2189
9.64k
  case OMPD_target_exit_data:
2190
9.64k
  case OMPD_target_update:
2191
9.64k
    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2192
196
        ParsedStmtContext()) {
2193
196
      Diag(Tok, diag::err_omp_immediate_directive)
2194
196
          << getOpenMPDirectiveName(DKind) << 0;
2195
196
    }
2196
9.64k
    HasAssociatedStatement = false;
2197
    // Fall through for further analysis.
2198
9.64k
    LLVM_FALLTHROUGH;
2199
221k
  case OMPD_parallel:
2200
221k
  case OMPD_simd:
2201
221k
  case OMPD_for:
2202
221k
  case OMPD_for_simd:
2203
221k
  case OMPD_sections:
2204
221k
  case OMPD_single:
2205
221k
  case OMPD_section:
2206
221k
  case OMPD_master:
2207
221k
  case OMPD_critical:
2208
221k
  case OMPD_parallel_for:
2209
221k
  case OMPD_parallel_for_simd:
2210
221k
  case OMPD_parallel_sections:
2211
221k
  case OMPD_parallel_master:
2212
221k
  case OMPD_task:
2213
221k
  case OMPD_ordered:
2214
221k
  case OMPD_atomic:
2215
221k
  case OMPD_target:
2216
221k
  case OMPD_teams:
2217
221k
  case OMPD_taskgroup:
2218
221k
  case OMPD_target_data:
2219
221k
  case OMPD_target_parallel:
2220
221k
  case OMPD_target_parallel_for:
2221
221k
  case OMPD_taskloop:
2222
221k
  case OMPD_taskloop_simd:
2223
221k
  case OMPD_master_taskloop:
2224
221k
  case OMPD_master_taskloop_simd:
2225
221k
  case OMPD_parallel_master_taskloop:
2226
221k
  case OMPD_parallel_master_taskloop_simd:
2227
221k
  case OMPD_distribute:
2228
221k
  case OMPD_distribute_parallel_for:
2229
221k
  case OMPD_distribute_parallel_for_simd:
2230
221k
  case OMPD_distribute_simd:
2231
221k
  case OMPD_target_parallel_for_simd:
2232
221k
  case OMPD_target_simd:
2233
221k
  case OMPD_teams_distribute:
2234
221k
  case OMPD_teams_distribute_simd:
2235
221k
  case OMPD_teams_distribute_parallel_for_simd:
2236
221k
  case OMPD_teams_distribute_parallel_for:
2237
221k
  case OMPD_target_teams:
2238
221k
  case OMPD_target_teams_distribute:
2239
221k
  case OMPD_target_teams_distribute_parallel_for:
2240
221k
  case OMPD_target_teams_distribute_parallel_for_simd:
2241
221k
  case OMPD_target_teams_distribute_simd: {
2242
    // Special processing for flush and depobj clauses.
2243
221k
    Token ImplicitTok;
2244
221k
    bool ImplicitClauseAllowed = false;
2245
221k
    if (DKind == OMPD_flush || 
DKind == OMPD_depobj220k
) {
2246
959
      ImplicitTok = Tok;
2247
959
      ImplicitClauseAllowed = true;
2248
959
    }
2249
221k
    ConsumeToken();
2250
    // Parse directive name of the 'critical' directive if any.
2251
221k
    if (DKind == OMPD_critical) {
2252
1.23k
      BalancedDelimiterTracker T(*this, tok::l_paren,
2253
1.23k
                                 tok::annot_pragma_openmp_end);
2254
1.23k
      if (!T.consumeOpen()) {
2255
172
        if (Tok.isAnyIdentifier()) {
2256
164
          DirName =
2257
164
              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2258
164
          ConsumeAnyToken();
2259
8
        } else {
2260
8
          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2261
8
        }
2262
172
        T.consumeClose();
2263
172
      }
2264
220k
    } else if (DKind == OMPD_cancellation_point || 
DKind == OMPD_cancel220k
) {
2265
867
      CancelRegion = parseOpenMPDirectiveKind(*this);
2266
867
      if (Tok.isNot(tok::annot_pragma_openmp_end))
2267
855
        ConsumeToken();
2268
867
    }
2269
221k
2270
221k
    if (isOpenMPLoopDirective(DKind))
2271
106k
      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2272
221k
    if (isOpenMPSimdDirective(DKind))
2273
62.9k
      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2274
221k
    ParseScope OMPDirectiveScope(this, ScopeFlags);
2275
221k
    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2276
221k
2277
373k
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2278
152k
      bool HasImplicitClause = false;
2279
152k
      if (ImplicitClauseAllowed && 
Tok.is(tok::l_paren)392
) {
2280
270
        HasImplicitClause = true;
2281
        // Push copy of the current token back to stream to properly parse
2282
        // pseudo-clause OMPFlushClause or OMPDepobjClause.
2283
270
        PP.EnterToken(Tok, /*IsReinject*/ true);
2284
270
        PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2285
270
        ConsumeAnyToken();
2286
270
      }
2287
152k
      OpenMPClauseKind CKind = Tok.isAnnotation()
2288
0
                                   ? OMPC_unknown
2289
152k
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
2290
152k
      if (HasImplicitClause) {
2291
270
        assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2292
270
        if (DKind == OMPD_flush) {
2293
80
          CKind = OMPC_flush;
2294
190
        } else {
2295
190
          assert(DKind == OMPD_depobj &&
2296
190
                 "Expected flush or depobj directives.");
2297
190
          CKind = OMPC_depobj;
2298
190
        }
2299
270
      }
2300
      // No more implicit clauses allowed.
2301
152k
      ImplicitClauseAllowed = false;
2302
152k
      Actions.StartOpenMPClause(CKind);
2303
152k
      HasImplicitClause = false;
2304
152k
      OMPClause *Clause = ParseOpenMPClause(
2305
152k
          DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2306
152k
      FirstClauses[unsigned(CKind)].setInt(true);
2307
152k
      if (Clause) {
2308
102k
        FirstClauses[unsigned(CKind)].setPointer(Clause);
2309
102k
        Clauses.push_back(Clause);
2310
102k
      }
2311
152k
2312
      // Skip ',' if any.
2313
152k
      if (Tok.is(tok::comma))
2314
8.06k
        ConsumeToken();
2315
152k
      Actions.EndOpenMPClause();
2316
152k
    }
2317
    // End location of the directive.
2318
221k
    EndLoc = Tok.getLocation();
2319
    // Consume final annot_pragma_openmp_end.
2320
221k
    ConsumeAnnotationToken();
2321
221k
2322
    // OpenMP [2.13.8, ordered Construct, Syntax]
2323
    // If the depend clause is specified, the ordered construct is a stand-alone
2324
    // directive.
2325
221k
    if (DKind == OMPD_ordered && 
FirstClauses[unsigned(OMPC_depend)].getInt()1.39k
) {
2326
373
      if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2327
24
          ParsedStmtContext()) {
2328
24
        Diag(Loc, diag::err_omp_immediate_directive)
2329
24
            << getOpenMPDirectiveName(DKind) << 1
2330
24
            << getOpenMPClauseName(OMPC_depend);
2331
24
      }
2332
373
      HasAssociatedStatement = false;
2333
373
    }
2334
221k
2335
221k
    StmtResult AssociatedStmt;
2336
221k
    if (HasAssociatedStatement) {
2337
      // The body is a block scope like in Lambdas and Blocks.
2338
211k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2339
      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2340
      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2341
      // should have at least one compound statement scope within it.
2342
211k
      ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2343
211k
      AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
2344
211k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2345
10.0k
    } else if (DKind == OMPD_target_update || 
DKind == OMPD_target_enter_data7.15k
||
2346
5.76k
               DKind == OMPD_target_exit_data) {
2347
5.61k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2348
5.61k
      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2349
5.61k
                        Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2350
5.61k
                                                  /*isStmtExpr=*/false));
2351
5.61k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2352
5.61k
    }
2353
221k
    Directive = Actions.ActOnOpenMPExecutableDirective(
2354
221k
        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2355
221k
        EndLoc);
2356
221k
2357
    // Exit scope.
2358
221k
    Actions.EndOpenMPDSABlock(Directive.get());
2359
221k
    OMPDirectiveScope.Exit();
2360
221k
    break;
2361
221k
  }
2362
16
  case OMPD_declare_simd:
2363
16
  case OMPD_declare_target:
2364
16
  case OMPD_end_declare_target:
2365
16
  case OMPD_requires:
2366
16
  case OMPD_begin_declare_variant:
2367
16
  case OMPD_end_declare_variant:
2368
16
  case OMPD_declare_variant:
2369
16
    Diag(Tok, diag::err_omp_unexpected_directive)
2370
16
        << 1 << getOpenMPDirectiveName(DKind);
2371
16
    SkipUntil(tok::annot_pragma_openmp_end);
2372
16
    break;
2373
40
  case OMPD_unknown:
2374
40
  default:
2375
40
    Diag(Tok, diag::err_omp_unknown_directive);
2376
40
    SkipUntil(tok::annot_pragma_openmp_end);
2377
40
    break;
2378
222k
  }
2379
222k
  return Directive;
2380
222k
}
2381
2382
// Parses simple list:
2383
//   simple-variable-list:
2384
//         '(' id-expression {, id-expression} ')'
2385
//
2386
bool Parser::ParseOpenMPSimpleVarList(
2387
    OpenMPDirectiveKind Kind,
2388
    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
2389
        Callback,
2390
3.34k
    bool AllowScopeSpecifier) {
2391
  // Parse '('.
2392
3.34k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2393
3.34k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
2394
3.34k
                         getOpenMPDirectiveName(Kind).data()))
2395
22
    return true;
2396
3.31k
  bool IsCorrect = true;
2397
3.31k
  bool NoIdentIsFound = true;
2398
3.31k
2399
  // Read tokens while ')' or annot_pragma_openmp_end is not found.
2400
6.91k
  while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)3.60k
) {
2401
3.59k
    CXXScopeSpec SS;
2402
3.59k
    UnqualifiedId Name;
2403
    // Read var name.
2404
3.59k
    Token PrevTok = Tok;
2405
3.59k
    NoIdentIsFound = false;
2406
3.59k
2407
3.59k
    if (AllowScopeSpecifier && 
getLangOpts().CPlusPlus3.13k
&&
2408
3.12k
        ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2409
0
                                       /*ObjectHadErrors=*/false, false)) {
2410
0
      IsCorrect = false;
2411
0
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2412
0
                StopBeforeMatch);
2413
3.59k
    } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2414
3.59k
                                  /*ObjectHadErrors=*/false, false, false,
2415
32
                                  false, false, nullptr, Name)) {
2416
32
      IsCorrect = false;
2417
32
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2418
32
                StopBeforeMatch);
2419
3.56k
    } else if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)3.27k
&&
2420
24
               Tok.isNot(tok::annot_pragma_openmp_end)) {
2421
16
      IsCorrect = false;
2422
16
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2423
16
                StopBeforeMatch);
2424
16
      Diag(PrevTok.getLocation(), diag::err_expected)
2425
16
          << tok::identifier
2426
16
          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2427
3.54k
    } else {
2428
3.54k
      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2429
3.54k
    }
2430
    // Consume ','.
2431
3.59k
    if (Tok.is(tok::comma)) {
2432
290
      ConsumeToken();
2433
290
    }
2434
3.59k
  }
2435
3.31k
2436
3.31k
  if (NoIdentIsFound) {
2437
16
    Diag(Tok, diag::err_expected) << tok::identifier;
2438
16
    IsCorrect = false;
2439
16
  }
2440
3.31k
2441
  // Parse ')'.
2442
3.31k
  IsCorrect = !T.consumeClose() && 
IsCorrect3.30k
;
2443
3.31k
2444
3.31k
  return !IsCorrect;
2445
3.31k
}
2446
2447
162
OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
2448
162
  SourceLocation Loc = Tok.getLocation();
2449
162
  ConsumeAnyToken();
2450
162
2451
  // Parse '('.
2452
162
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2453
162
  if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
2454
2
    return nullptr;
2455
160
  SmallVector<Sema::UsesAllocatorsData, 4> Data;
2456
236
  do {
2457
236
    ExprResult Allocator = ParseCXXIdExpression();
2458
236
    if (Allocator.isInvalid()) {
2459
6
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2460
6
                StopBeforeMatch);
2461
6
      break;
2462
6
    }
2463
230
    Sema::UsesAllocatorsData &D = Data.emplace_back();
2464
230
    D.Allocator = Allocator.get();
2465
230
    if (Tok.is(tok::l_paren)) {
2466
52
      BalancedDelimiterTracker T(*this, tok::l_paren,
2467
52
                                 tok::annot_pragma_openmp_end);
2468
52
      T.consumeOpen();
2469
52
      ExprResult AllocatorTraits = ParseCXXIdExpression();
2470
52
      T.consumeClose();
2471
52
      if (AllocatorTraits.isInvalid()) {
2472
4
        SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2473
4
                  StopBeforeMatch);
2474
4
        break;
2475
4
      }
2476
48
      D.AllocatorTraits = AllocatorTraits.get();
2477
48
      D.LParenLoc = T.getOpenLocation();
2478
48
      D.RParenLoc = T.getCloseLocation();
2479
48
    }
2480
226
    if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)150
)
2481
4
      Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
2482
    // Parse ','
2483
226
    if (Tok.is(tok::comma))
2484
76
      ConsumeAnyToken();
2485
226
  } while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)80
);
2486
160
  T.consumeClose();
2487
160
  return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
2488
160
                                                T.getCloseLocation(), Data);
2489
160
}
2490
2491
/// Parsing of OpenMP clauses.
2492
///
2493
///    clause:
2494
///       if-clause | final-clause | num_threads-clause | safelen-clause |
2495
///       default-clause | private-clause | firstprivate-clause | shared-clause
2496
///       | linear-clause | aligned-clause | collapse-clause |
2497
///       lastprivate-clause | reduction-clause | proc_bind-clause |
2498
///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
2499
///       mergeable-clause | flush-clause | read-clause | write-clause |
2500
///       update-clause | capture-clause | seq_cst-clause | device-clause |
2501
///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
2502
///       thread_limit-clause | priority-clause | grainsize-clause |
2503
///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
2504
///       from-clause | is_device_ptr-clause | task_reduction-clause |
2505
///       in_reduction-clause | allocator-clause | allocate-clause |
2506
///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
2507
///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
2508
///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
2509
///
2510
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2511
152k
                                     OpenMPClauseKind CKind, bool FirstClause) {
2512
152k
  OMPClauseKind = CKind;
2513
152k
  OMPClause *Clause = nullptr;
2514
152k
  bool ErrorFound = false;
2515
152k
  bool WrongDirective = false;
2516
  // Check if clause is allowed for the given directive.
2517
152k
  if (CKind != OMPC_unknown &&
2518
149k
      !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
2519
1.43k
    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
2520
1.43k
                                               << getOpenMPDirectiveName(DKind);
2521
1.43k
    ErrorFound = true;
2522
1.43k
    WrongDirective = true;
2523
1.43k
  }
2524
152k
2525
152k
  switch (CKind) {
2526
21.6k
  case OMPC_final:
2527
21.6k
  case OMPC_num_threads:
2528
21.6k
  case OMPC_safelen:
2529
21.6k
  case OMPC_simdlen:
2530
21.6k
  case OMPC_collapse:
2531
21.6k
  case OMPC_ordered:
2532
21.6k
  case OMPC_num_teams:
2533
21.6k
  case OMPC_thread_limit:
2534
21.6k
  case OMPC_priority:
2535
21.6k
  case OMPC_grainsize:
2536
21.6k
  case OMPC_num_tasks:
2537
21.6k
  case OMPC_hint:
2538
21.6k
  case OMPC_allocator:
2539
21.6k
  case OMPC_depobj:
2540
21.6k
  case OMPC_detach:
2541
    // OpenMP [2.5, Restrictions]
2542
    //  At most one num_threads clause can appear on the directive.
2543
    // OpenMP [2.8.1, simd construct, Restrictions]
2544
    //  Only one safelen  clause can appear on a simd directive.
2545
    //  Only one simdlen  clause can appear on a simd directive.
2546
    //  Only one collapse clause can appear on a simd directive.
2547
    // OpenMP [2.11.1, task Construct, Restrictions]
2548
    //  At most one if clause can appear on the directive.
2549
    //  At most one final clause can appear on the directive.
2550
    // OpenMP [teams Construct, Restrictions]
2551
    //  At most one num_teams clause can appear on the directive.
2552
    //  At most one thread_limit clause can appear on the directive.
2553
    // OpenMP [2.9.1, task Construct, Restrictions]
2554
    // At most one priority clause can appear on the directive.
2555
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
2556
    // At most one grainsize clause can appear on the directive.
2557
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
2558
    // At most one num_tasks clause can appear on the directive.
2559
    // OpenMP [2.11.3, allocate Directive, Restrictions]
2560
    // At most one allocator clause can appear on the directive.
2561
    // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
2562
    // At most one detach clause can appear on the directive.
2563
21.6k
    if (!FirstClause) {
2564
1.74k
      Diag(Tok, diag::err_omp_more_one_clause)
2565
1.74k
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2566
1.74k
      ErrorFound = true;
2567
1.74k
    }
2568
21.6k
2569
21.6k
    if (CKind == OMPC_ordered && 
PP.LookAhead(/*N=*/0).isNot(tok::l_paren)1.18k
)
2570
426
      Clause = ParseOpenMPClause(CKind, WrongDirective);
2571
21.2k
    else
2572
21.2k
      Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
2573
21.6k
    break;
2574
2.92k
  case OMPC_default:
2575
2.92k
  case OMPC_proc_bind:
2576
2.92k
  case OMPC_atomic_default_mem_order:
2577
2.92k
  case OMPC_order:
2578
    // OpenMP [2.14.3.1, Restrictions]
2579
    //  Only a single default clause may be specified on a parallel, task or
2580
    //  teams directive.
2581
    // OpenMP [2.5, parallel Construct, Restrictions]
2582
    //  At most one proc_bind clause can appear on the directive.
2583
    // OpenMP [5.0, Requires directive, Restrictions]
2584
    //  At most one atomic_default_mem_order clause can appear
2585
    //  on the directive
2586
2.92k
    if (!FirstClause && 
CKind != OMPC_order129
) {
2587
129
      Diag(Tok, diag::err_omp_more_one_clause)
2588
129
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2589
129
      ErrorFound = true;
2590
129
    }
2591
2.92k
2592
2.92k
    Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
2593
2.92k
    break;
2594
7.28k
  case OMPC_device:
2595
7.28k
  case OMPC_schedule:
2596
7.28k
  case OMPC_dist_schedule:
2597
7.28k
  case OMPC_defaultmap:
2598
    // OpenMP [2.7.1, Restrictions, p. 3]
2599
    //  Only one schedule clause can appear on a loop directive.
2600
    // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
2601
    //  At most one defaultmap clause can appear on the directive.
2602
    // OpenMP 5.0 [2.12.5, target construct, Restrictions]
2603
    //  At most one device clause can appear on the directive.
2604
7.28k
    if ((getLangOpts().OpenMP < 50 || 
CKind != OMPC_defaultmap5.59k
) &&
2605
6.08k
        !FirstClause) {
2606
180
      Diag(Tok, diag::err_omp_more_one_clause)
2607
180
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2608
180
      ErrorFound = true;
2609
180
    }
2610
7.28k
    LLVM_FALLTHROUGH;
2611
17.5k
  case OMPC_if:
2612
17.5k
    Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
2613
17.5k
    break;
2614
4.93k
  case OMPC_nowait:
2615
4.93k
  case OMPC_untied:
2616
4.93k
  case OMPC_mergeable:
2617
4.93k
  case OMPC_read:
2618
4.93k
  case OMPC_write:
2619
4.93k
  case OMPC_capture:
2620
4.93k
  case OMPC_seq_cst:
2621
4.93k
  case OMPC_acq_rel:
2622
4.93k
  case OMPC_acquire:
2623
4.93k
  case OMPC_release:
2624
4.93k
  case OMPC_relaxed:
2625
4.93k
  case OMPC_threads:
2626
4.93k
  case OMPC_simd:
2627
4.93k
  case OMPC_nogroup:
2628
4.93k
  case OMPC_unified_address:
2629
4.93k
  case OMPC_unified_shared_memory:
2630
4.93k
  case OMPC_reverse_offload:
2631
4.93k
  case OMPC_dynamic_allocators:
2632
4.93k
  case OMPC_destroy:
2633
    // OpenMP [2.7.1, Restrictions, p. 9]
2634
    //  Only one ordered clause can appear on a loop directive.
2635
    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2636
    //  Only one nowait clause can appear on a for directive.
2637
    // OpenMP [5.0, Requires directive, Restrictions]
2638
    //   Each of the requires clauses can appear at most once on the directive.
2639
4.93k
    if (!FirstClause) {
2640
184
      Diag(Tok, diag::err_omp_more_one_clause)
2641
184
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2642
184
      ErrorFound = true;
2643
184
    }
2644
4.93k
2645
4.93k
    Clause = ParseOpenMPClause(CKind, WrongDirective);
2646
4.93k
    break;
2647
469
  case OMPC_update:
2648
469
    if (!FirstClause) {
2649
14
      Diag(Tok, diag::err_omp_more_one_clause)
2650
14
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2651
14
      ErrorFound = true;
2652
14
    }
2653
469
2654
469
    Clause = (DKind == OMPD_depobj)
2655
34
                 ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2656
435
                 : ParseOpenMPClause(CKind, WrongDirective);
2657
469
    break;
2658
101k
  case OMPC_private:
2659
101k
  case OMPC_firstprivate:
2660
101k
  case OMPC_lastprivate:
2661
101k
  case OMPC_shared:
2662
101k
  case OMPC_reduction:
2663
101k
  case OMPC_task_reduction:
2664
101k
  case OMPC_in_reduction:
2665
101k
  case OMPC_linear:
2666
101k
  case OMPC_aligned:
2667
101k
  case OMPC_copyin:
2668
101k
  case OMPC_copyprivate:
2669
101k
  case OMPC_flush:
2670
101k
  case OMPC_depend:
2671
101k
  case OMPC_map:
2672
101k
  case OMPC_to:
2673
101k
  case OMPC_from:
2674
101k
  case OMPC_use_device_ptr:
2675
101k
  case OMPC_use_device_addr:
2676
101k
  case OMPC_is_device_ptr:
2677
101k
  case OMPC_allocate:
2678
101k
  case OMPC_nontemporal:
2679
101k
  case OMPC_inclusive:
2680
101k
  case OMPC_exclusive:
2681
101k
  case OMPC_affinity:
2682
101k
    Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
2683
101k
    break;
2684
162
  case OMPC_uses_allocators:
2685
162
    Clause = ParseOpenMPUsesAllocatorClause(DKind);
2686
162
    break;
2687
3.37k
  case OMPC_device_type:
2688
3.37k
  case OMPC_unknown:
2689
3.37k
    skipUntilPragmaOpenMPEnd(DKind);
2690
3.37k
    break;
2691
4
  case OMPC_threadprivate:
2692
4
  case OMPC_uniform:
2693
4
  case OMPC_match:
2694
4
    if (!WrongDirective)
2695
0
      Diag(Tok, diag::err_omp_unexpected_clause)
2696
0
          << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2697
4
    SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
2698
4
    break;
2699
0
  default:
2700
0
    break;
2701
152k
  }
2702
152k
  return ErrorFound ? 
nullptr3.65k
:
Clause149k
;
2703
152k
}
2704
2705
/// Parses simple expression in parens for single-expression clauses of OpenMP
2706
/// constructs.
2707
/// \param RLoc Returned location of right paren.
2708
ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
2709
                                         SourceLocation &RLoc,
2710
23.4k
                                         bool IsAddressOfOperand) {
2711
23.4k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2712
23.4k
  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2713
1.18k
    return ExprError();
2714
22.2k
2715
22.2k
  SourceLocation ELoc = Tok.getLocation();
2716
22.2k
  ExprResult LHS(ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
2717
22.2k
                                     NotTypeCast));
2718
22.2k
  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
2719
22.2k
  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2720
22.2k
2721
  // Parse ')'.
2722
22.2k
  RLoc = Tok.getLocation();
2723
22.2k
  if (!T.consumeClose())
2724
17.5k
    RLoc = T.getCloseLocation();
2725
22.2k
2726
22.2k
  return Val;
2727
22.2k
}
2728
2729
/// Parsing of OpenMP clauses with single expressions like 'final',
2730
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
2731
/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
2732
/// 'detach'.
2733
///
2734
///    final-clause:
2735
///      'final' '(' expression ')'
2736
///
2737
///    num_threads-clause:
2738
///      'num_threads' '(' expression ')'
2739
///
2740
///    safelen-clause:
2741
///      'safelen' '(' expression ')'
2742
///
2743
///    simdlen-clause:
2744
///      'simdlen' '(' expression ')'
2745
///
2746
///    collapse-clause:
2747
///      'collapse' '(' expression ')'
2748
///
2749
///    priority-clause:
2750
///      'priority' '(' expression ')'
2751
///
2752
///    grainsize-clause:
2753
///      'grainsize' '(' expression ')'
2754
///
2755
///    num_tasks-clause:
2756
///      'num_tasks' '(' expression ')'
2757
///
2758
///    hint-clause:
2759
///      'hint' '(' expression ')'
2760
///
2761
///    allocator-clause:
2762
///      'allocator' '(' expression ')'
2763
///
2764
///    detach-clause:
2765
///      'detach' '(' event-handler-expression ')'
2766
///
2767
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
2768
21.2k
                                               bool ParseOnly) {
2769
21.2k
  SourceLocation Loc = ConsumeToken();
2770
21.2k
  SourceLocation LLoc = Tok.getLocation();
2771
21.2k
  SourceLocation RLoc;
2772
21.2k
2773
21.2k
  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
2774
21.2k
2775
21.2k
  if (Val.isInvalid())
2776
4.96k
    return nullptr;
2777
16.2k
2778
16.2k
  if (ParseOnly)
2779
112
    return nullptr;
2780
16.1k
  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
2781
16.1k
}
2782
2783
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
2784
///
2785
///    default-clause:
2786
///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
2787
///
2788
///    proc_bind-clause:
2789
///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
2790
///
2791
///    update-clause:
2792
///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
2793
///
2794
OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
2795
2.95k
                                           bool ParseOnly) {
2796
2.95k
  llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
2797
2.95k
  if (!Val || 
ParseOnly2.75k
)
2798
351
    return nullptr;
2799
2.60k
  if (getLangOpts().OpenMP < 51 && 
Kind == OMPC_default2.12k
&&
2800
1.19k
      static_cast<DefaultKind>(Val.getValue().Type) ==
2801
14
          OMP_DEFAULT_firstprivate) {
2802
14
    Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
2803
14
        << getOpenMPClauseName(OMPC_firstprivate)
2804
14
        << getOpenMPClauseName(OMPC_default) << "5.1";
2805
14
    return nullptr;
2806
14
  }
2807
2.59k
  return Actions.ActOnOpenMPSimpleClause(
2808
2.59k
      Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
2809
2.59k
      Val.getValue().Loc, Val.getValue().RLoc);
2810
2.59k
}
2811
2812
/// Parsing of OpenMP clauses like 'ordered'.
2813
///
2814
///    ordered-clause:
2815
///         'ordered'
2816
///
2817
///    nowait-clause:
2818
///         'nowait'
2819
///
2820
///    untied-clause:
2821
///         'untied'
2822
///
2823
///    mergeable-clause:
2824
///         'mergeable'
2825
///
2826
///    read-clause:
2827
///         'read'
2828
///
2829
///    threads-clause:
2830
///         'threads'
2831
///
2832
///    simd-clause:
2833
///         'simd'
2834
///
2835
///    nogroup-clause:
2836
///         'nogroup'
2837
///
2838
5.79k
OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
2839
5.79k
  SourceLocation Loc = Tok.getLocation();
2840
5.79k
  ConsumeAnyToken();
2841
5.79k
2842
5.79k
  if (ParseOnly)
2843
265
    return nullptr;
2844
5.52k
  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
2845
5.52k
}
2846
2847
/// Parsing of OpenMP clauses with single expressions and some additional
2848
/// argument like 'schedule' or 'dist_schedule'.
2849
///
2850
///    schedule-clause:
2851
///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
2852
///      ')'
2853
///
2854
///    if-clause:
2855
///      'if' '(' [ directive-name-modifier ':' ] expression ')'
2856
///
2857
///    defaultmap:
2858
///      'defaultmap' '(' modifier [ ':' kind ] ')'
2859
///
2860
///    device-clause:
2861
///      'device' '(' [ device-modifier ':' ] expression ')'
2862
///
2863
OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
2864
                                                      OpenMPClauseKind Kind,
2865
17.5k
                                                      bool ParseOnly) {
2866
17.5k
  SourceLocation Loc = ConsumeToken();
2867
17.5k
  SourceLocation DelimLoc;
2868
  // Parse '('.
2869
17.5k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2870
17.5k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
2871
17.5k
                         getOpenMPClauseName(Kind).data()))
2872
394
    return nullptr;
2873
17.2k
2874
17.2k
  ExprResult Val;
2875
17.2k
  SmallVector<unsigned, 4> Arg;
2876
17.2k
  SmallVector<SourceLocation, 4> KLoc;
2877
17.2k
  if (Kind == OMPC_schedule) {
2878
2.82k
    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
2879
2.82k
    Arg.resize(NumberOfElements);
2880
2.82k
    KLoc.resize(NumberOfElements);
2881
2.82k
    Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
2882
2.82k
    Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
2883
2.82k
    Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
2884
2.82k
    unsigned KindModifier = getOpenMPSimpleClauseType(
2885
2.77k
        Kind, Tok.isAnnotation() ? 
""48
: PP.getSpelling(Tok),
2886
2.82k
        getLangOpts().OpenMP);
2887
2.82k
    if (KindModifier > OMPC_SCHEDULE_unknown) {
2888
      // Parse 'modifier'
2889
176
      Arg[Modifier1] = KindModifier;
2890
176
      KLoc[Modifier1] = Tok.getLocation();
2891
176
      if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2892
176
          Tok.isNot(tok::annot_pragma_openmp_end))
2893
176
        ConsumeAnyToken();
2894
176
      if (Tok.is(tok::comma)) {
2895
        // Parse ',' 'modifier'
2896
36
        ConsumeAnyToken();
2897
36
        KindModifier = getOpenMPSimpleClauseType(
2898
32
            Kind, Tok.isAnnotation() ? 
""4
: PP.getSpelling(Tok),
2899
36
            getLangOpts().OpenMP);
2900
36
        Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
2901
28
                             ? KindModifier
2902
8
                             : (unsigned)OMPC_SCHEDULE_unknown;
2903
36
        KLoc[Modifier2] = Tok.getLocation();
2904
36
        if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2905
36
            Tok.isNot(tok::annot_pragma_openmp_end))
2906
32
          ConsumeAnyToken();
2907
36
      }
2908
      // Parse ':'
2909
176
      if (Tok.is(tok::colon))
2910
164
        ConsumeAnyToken();
2911
12
      else
2912
12
        Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
2913
176
      KindModifier = getOpenMPSimpleClauseType(
2914
160
          Kind, Tok.isAnnotation() ? 
""16
: PP.getSpelling(Tok),
2915
176
          getLangOpts().OpenMP);
2916
176
    }
2917
2.82k
    Arg[ScheduleKind] = KindModifier;
2918
2.82k
    KLoc[ScheduleKind] = Tok.getLocation();
2919
2.82k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)2.77k
&&
2920
2.77k
        Tok.isNot(tok::annot_pragma_openmp_end))
2921
2.71k
      ConsumeAnyToken();
2922
2.82k
    if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
2923
1.84k
         Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
2924
999
         Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
2925
2.17k
        Tok.is(tok::comma))
2926
1.23k
      DelimLoc = ConsumeAnyToken();
2927
14.3k
  } else if (Kind == OMPC_dist_schedule) {
2928
1.52k
    Arg.push_back(getOpenMPSimpleClauseType(
2929
1.47k
        Kind, Tok.isAnnotation() ? 
""48
: PP.getSpelling(Tok),
2930
1.52k
        getLangOpts().OpenMP));
2931
1.52k
    KLoc.push_back(Tok.getLocation());
2932
1.52k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.47k
&&
2933
1.47k
        Tok.isNot(tok::annot_pragma_openmp_end))
2934
1.42k
      ConsumeAnyToken();
2935
1.52k
    if (Arg.back() == OMPC_DIST_SCHEDULE_static && 
Tok.is(tok::comma)1.37k
)
2936
910
      DelimLoc = ConsumeAnyToken();
2937
12.8k
  } else if (Kind == OMPC_defaultmap) {
2938
    // Get a defaultmap modifier
2939
1.55k
    unsigned Modifier = getOpenMPSimpleClauseType(
2940
1.47k
        Kind, Tok.isAnnotation() ? 
""80
: PP.getSpelling(Tok),
2941
1.55k
        getLangOpts().OpenMP);
2942
    // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
2943
    // pointer
2944
1.55k
    if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
2945
80
      Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
2946
1.55k
    Arg.push_back(Modifier);
2947
1.55k
    KLoc.push_back(Tok.getLocation());
2948
1.55k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.47k
&&
2949
1.47k
        Tok.isNot(tok::annot_pragma_openmp_end))
2950
1.39k
      ConsumeAnyToken();
2951
    // Parse ':'
2952
1.55k
    if (Tok.is(tok::colon) || 
getLangOpts().OpenMP < 50566
) {
2953
1.26k
      if (Tok.is(tok::colon))
2954
990
        ConsumeAnyToken();
2955
272
      else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
2956
192
        Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
2957
      // Get a defaultmap kind
2958
1.26k
      Arg.push_back(getOpenMPSimpleClauseType(
2959
1.02k
          Kind, Tok.isAnnotation() ? 
""240
: PP.getSpelling(Tok),
2960
1.26k
          getLangOpts().OpenMP));
2961
1.26k
      KLoc.push_back(Tok.getLocation());
2962
1.26k
      if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.18k
&&
2963
1.10k
          Tok.isNot(tok::annot_pragma_openmp_end))
2964
862
        ConsumeAnyToken();
2965
294
    } else {
2966
294
      Arg.push_back(OMPC_DEFAULTMAP_unknown);
2967
294
      KLoc.push_back(SourceLocation());
2968
294
    }
2969
11.2k
  } else if (Kind == OMPC_device) {
2970
    // Only target executable directives support extended device construct.
2971
1.18k
    if (isOpenMPTargetExecutionDirective(DKind) && 
getLangOpts().OpenMP >= 50786
&&
2972
622
        NextToken().is(tok::colon)) {
2973
      // Parse optional <device modifier> ':'
2974
22
      Arg.push_back(getOpenMPSimpleClauseType(
2975
22
          Kind, Tok.isAnnotation() ? 
""0
: PP.getSpelling(Tok),
2976
22
          getLangOpts().OpenMP));
2977
22
      KLoc.push_back(Tok.getLocation());
2978
22
      ConsumeAnyToken();
2979
      // Parse ':'
2980
22
      ConsumeAnyToken();
2981
1.15k
    } else {
2982
1.15k
      Arg.push_back(OMPC_DEVICE_unknown);
2983
1.15k
      KLoc.emplace_back();
2984
1.15k
    }
2985
10.1k
  } else {
2986
10.1k
    assert(Kind == OMPC_if);
2987
10.1k
    KLoc.push_back(Tok.getLocation());
2988
10.1k
    TentativeParsingAction TPA(*this);
2989
10.1k
    auto DK = parseOpenMPDirectiveKind(*this);
2990
10.1k
    Arg.push_back(DK);
2991
10.1k
    if (DK != OMPD_unknown) {
2992
5.34k
      ConsumeToken();
2993
5.34k
      if (Tok.is(tok::colon) && 
getLangOpts().OpenMP > 405.25k
) {
2994
5.25k
        TPA.Commit();
2995
5.25k
        DelimLoc = ConsumeToken();
2996
96
      } else {
2997
96
        TPA.Revert();
2998
96
        Arg.back() = unsigned(OMPD_unknown);
2999
96
      }
3000
4.77k
    } else {
3001
4.77k
      TPA.Revert();
3002
4.77k
    }
3003
10.1k
  }
3004
17.2k
3005
17.2k
  bool NeedAnExpression = (Kind == OMPC_schedule && 
DelimLoc.isValid()2.82k
) ||
3006
15.9k
                          (Kind == OMPC_dist_schedule && 
DelimLoc.isValid()1.52k
) ||
3007
15.0k
                          Kind == OMPC_if || 
Kind == OMPC_device4.93k
;
3008
17.2k
  if (NeedAnExpression) {
3009
13.4k
    SourceLocation ELoc = Tok.getLocation();
3010
13.4k
    ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3011
13.4k
    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3012
13.4k
    Val =
3013
13.4k
        Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3014
13.4k
  }
3015
17.2k
3016
  // Parse ')'.
3017
17.2k
  SourceLocation RLoc = Tok.getLocation();
3018
17.2k
  if (!T.consumeClose())
3019
14.5k
    RLoc = T.getCloseLocation();
3020
17.2k
3021
17.2k
  if (NeedAnExpression && 
Val.isInvalid()13.4k
)
3022
1.15k
    return nullptr;
3023
16.0k
3024
16.0k
  if (ParseOnly)
3025
4
    return nullptr;
3026
16.0k
  return Actions.ActOnOpenMPSingleExprWithArgClause(
3027
16.0k
      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3028
16.0k
}
3029
3030
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3031
34.8k
                             UnqualifiedId &ReductionId) {
3032
34.8k
  if (ReductionIdScopeSpec.isEmpty()) {
3033
34.7k
    auto OOK = OO_None;
3034
34.7k
    switch (P.getCurToken().getKind()) {
3035
14.8k
    case tok::plus:
3036
14.8k
      OOK = OO_Plus;
3037
14.8k
      break;
3038
1.99k
    case tok::minus:
3039
1.99k
      OOK = OO_Minus;
3040
1.99k
      break;
3041
2.36k
    case tok::star:
3042
2.36k
      OOK = OO_Star;
3043
2.36k
      break;
3044
1.01k
    case tok::amp:
3045
1.01k
      OOK = OO_Amp;
3046
1.01k
      break;
3047
972
    case tok::pipe:
3048
972
      OOK = OO_Pipe;
3049
972
      break;
3050
1.83k
    case tok::caret:
3051
1.83k
      OOK = OO_Caret;
3052
1.83k
      break;
3053
2.79k
    case tok::ampamp:
3054
2.79k
      OOK = OO_AmpAmp;
3055
2.79k
      break;
3056
860
    case tok::pipepipe:
3057
860
      OOK = OO_PipePipe;
3058
860
      break;
3059
8.05k
    default:
3060
8.05k
      break;
3061
34.7k
    }
3062
34.7k
    if (OOK != OO_None) {
3063
26.7k
      SourceLocation OpLoc = P.ConsumeToken();
3064
26.7k
      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3065
26.7k
      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3066
26.7k
      return false;
3067
26.7k
    }
3068
8.09k
  }
3069
8.09k
  return P.ParseUnqualifiedId(
3070
8.09k
      ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3071
8.09k
      /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3072
8.09k
      /*AllowDestructorName*/ false,
3073
8.09k
      /*AllowConstructorName*/ false,
3074
8.09k
      /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3075
8.09k
}
3076
3077
/// Checks if the token is a valid map-type-modifier.
3078
/// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
3079
9.54k
static OpenMPMapModifierKind isMapModifier(Parser &P) {
3080
9.54k
  Token Tok = P.getCurToken();
3081
9.54k
  if (!Tok.is(tok::identifier))
3082
162
    return OMPC_MAP_MODIFIER_unknown;
3083
9.38k
3084
9.38k
  Preprocessor &PP = P.getPreprocessor();
3085
9.38k
  OpenMPMapModifierKind TypeModifier =
3086
9.38k
      static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3087
9.38k
          OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3088
9.38k
  return TypeModifier;
3089
9.38k
}
3090
3091
/// Parse the mapper modifier in map, to, and from clauses.
3092
570
bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3093
  // Parse '('.
3094
570
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3095
570
  if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3096
40
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3097
40
              StopBeforeMatch);
3098
40
    return true;
3099
40
  }
3100
  // Parse mapper-identifier
3101
530
  if (getLangOpts().CPlusPlus)
3102
432
    ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3103
432
                                   /*ObjectType=*/nullptr,
3104
432
                                   /*ObjectHadErrors=*/false,
3105
432
                                   /*EnteringContext=*/false);
3106
530
  if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)96
) {
3107
68
    Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3108
68
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3109
68
              StopBeforeMatch);
3110
68
    return true;
3111
68
  }
3112
462
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
3113
462
  Data.ReductionOrMapperId = DeclarationNameInfo(
3114
462
      DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3115
462
  ConsumeToken();
3116
  // Parse ')'.
3117
462
  return T.consumeClose();
3118
462
}
3119
3120
/// Parse map-type-modifiers in map clause.
3121
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3122
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3123
/// present
3124
7.68k
bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3125
9.91k
  while (getCurToken().isNot(tok::colon)) {
3126
9.54k
    OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3127
9.54k
    if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3128
8.46k
        TypeModifier == OMPC_MAP_MODIFIER_close ||
3129
8.00k
        TypeModifier == OMPC_MAP_MODIFIER_present) {
3130
1.67k
      Data.MapTypeModifiers.push_back(TypeModifier);
3131
1.67k
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3132
1.67k
      ConsumeToken();
3133
7.86k
    } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3134
194
      Data.MapTypeModifiers.push_back(TypeModifier);
3135
194
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3136
194
      ConsumeToken();
3137
194
      if (parseMapperModifier(Data))
3138
20
        return true;
3139
7.67k
    } else {
3140
      // For the case of unknown map-type-modifier or a map-type.
3141
      // Map-type is followed by a colon; the function returns when it
3142
      // encounters a token followed by a colon.
3143
7.67k
      if (Tok.is(tok::comma)) {
3144
60
        Diag(Tok, diag::err_omp_map_type_modifier_missing);
3145
60
        ConsumeToken();
3146
60
        continue;
3147
60
      }
3148
      // Potential map-type token as it is followed by a colon.
3149
7.61k
      if (PP.LookAhead(0).is(tok::colon))
3150
7.30k
        return false;
3151
310
      Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3152
256
          << (getLangOpts().OpenMP >= 51 ? 
154
: 0);
3153
310
      ConsumeToken();
3154
310
    }
3155
2.16k
    if (getCurToken().is(tok::comma))
3156
1.45k
      ConsumeToken();
3157
2.16k
  }
3158
364
  return false;
3159
7.68k
}
3160
3161
/// Checks if the token is a valid map-type.
3162
/// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
3163
7.30k
static OpenMPMapClauseKind isMapType(Parser &P) {
3164
7.30k
  Token Tok = P.getCurToken();
3165
  // The map-type token can be either an identifier or the C++ delete keyword.
3166
7.30k
  if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3167
0
    return OMPC_MAP_unknown;
3168
7.30k
  Preprocessor &PP = P.getPreprocessor();
3169
7.30k
  OpenMPMapClauseKind MapType =
3170
7.30k
      static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3171
7.30k
          OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3172
7.30k
  return MapType;
3173
7.30k
}
3174
3175
/// Parse map-type in map clause.
3176
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3177
/// where, map-type ::= to | from | tofrom | alloc | release | delete
3178
7.66k
static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3179
7.66k
  Token Tok = P.getCurToken();
3180
7.66k
  if (Tok.is(tok::colon)) {
3181
364
    P.Diag(Tok, diag::err_omp_map_type_missing);
3182
364
    return;
3183
364
  }
3184
7.30k
  Data.ExtraModifier = isMapType(P);
3185
7.30k
  if (Data.ExtraModifier == OMPC_MAP_unknown)
3186
248
    P.Diag(Tok, diag::err_omp_unknown_map_type);
3187
7.30k
  P.ConsumeToken();
3188
7.30k
}
3189
3190
/// Parses simple expression in parens for single-expression clauses of OpenMP
3191
/// constructs.
3192
66
ExprResult Parser::ParseOpenMPIteratorsExpr() {
3193
66
  assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3194
66
         "Expected 'iterator' token.");
3195
66
  SourceLocation IteratorKwLoc = ConsumeToken();
3196
66
3197
66
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3198
66
  if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3199
4
    return ExprError();
3200
62
3201
62
  SourceLocation LLoc = T.getOpenLocation();
3202
62
  SmallVector<Sema::OMPIteratorData, 4> Data;
3203
132
  while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)82
) {
3204
    // Check if the type parsing is required.
3205
74
    ParsedType IteratorType;
3206
74
    if (Tok.isNot(tok::identifier) || 
NextToken().isNot(tok::equal)52
) {
3207
      // identifier '=' is not found - parse type.
3208
46
      TypeResult TR = ParseTypeName();
3209
46
      if (TR.isInvalid()) {
3210
4
        T.skipToEnd();
3211
4
        return ExprError();
3212
4
      }
3213
42
      IteratorType = TR.get();
3214
42
    }
3215
74
3216
    // Parse identifier.
3217
70
    IdentifierInfo *II = nullptr;
3218
70
    SourceLocation IdLoc;
3219
70
    if (Tok.is(tok::identifier)) {
3220
70
      II = Tok.getIdentifierInfo();
3221
70
      IdLoc = ConsumeToken();
3222
0
    } else {
3223
0
      Diag(Tok, diag::err_expected_unqualified_id) << 0;
3224
0
    }
3225
70
3226
    // Parse '='.
3227
70
    SourceLocation AssignLoc;
3228
70
    if (Tok.is(tok::equal))
3229
66
      AssignLoc = ConsumeToken();
3230
4
    else
3231
4
      Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3232
70
3233
    // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3234
70
    ColonProtectionRAIIObject ColonRAII(*this);
3235
    // Parse <begin>
3236
70
    SourceLocation Loc = Tok.getLocation();
3237
70
    ExprResult LHS = ParseCastExpression(AnyCastExpr);
3238
70
    ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3239
70
        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3240
70
    Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3241
70
                                        /*DiscardedValue=*/false);
3242
    // Parse ':'.
3243
70
    SourceLocation ColonLoc;
3244
70
    if (Tok.is(tok::colon))
3245
66
      ColonLoc = ConsumeToken();
3246
70
3247
    // Parse <end>
3248
70
    Loc = Tok.getLocation();
3249
70
    LHS = ParseCastExpression(AnyCastExpr);
3250
70
    ExprResult End = Actions.CorrectDelayedTyposInExpr(
3251
70
        ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3252
70
    End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3253
70
                                      /*DiscardedValue=*/false);
3254
70
3255
70
    SourceLocation SecColonLoc;
3256
70
    ExprResult Step;
3257
    // Parse optional step.
3258
70
    if (Tok.is(tok::colon)) {
3259
      // Parse ':'
3260
28
      SecColonLoc = ConsumeToken();
3261
      // Parse <step>
3262
28
      Loc = Tok.getLocation();
3263
28
      LHS = ParseCastExpression(AnyCastExpr);
3264
28
      Step = Actions.CorrectDelayedTyposInExpr(
3265
28
          ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3266
28
      Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3267
28
                                         /*DiscardedValue=*/false);
3268
28
    }
3269
70
3270
    // Parse ',' or ')'
3271
70
    if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)54
)
3272
8
      Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3273
70
    if (Tok.is(tok::comma))
3274
16
      ConsumeToken();
3275
70
3276
70
    Sema::OMPIteratorData &D = Data.emplace_back();
3277
70
    D.DeclIdent = II;
3278
70
    D.DeclIdentLoc = IdLoc;
3279
70
    D.Type = IteratorType;
3280
70
    D.AssignLoc = AssignLoc;
3281
70
    D.ColonLoc = ColonLoc;
3282
70
    D.SecColonLoc = SecColonLoc;
3283
70
    D.Range.Begin = Begin.get();
3284
70
    D.Range.End = End.get();
3285
70
    D.Range.Step = Step.get();
3286
70
  }
3287
62
3288
  // Parse ')'.
3289
58
  SourceLocation RLoc = Tok.getLocation();
3290
58
  if (!T.consumeClose())
3291
50
    RLoc = T.getCloseLocation();
3292
58
3293
58
  return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
3294
58
                                      Data);
3295
62
}
3296
3297
/// Parses clauses with list.
3298
bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
3299
                                OpenMPClauseKind Kind,
3300
                                SmallVectorImpl<Expr *> &Vars,
3301
102k
                                OpenMPVarListDataTy &Data) {
3302
102k
  UnqualifiedId UnqualifiedReductionId;
3303
102k
  bool InvalidReductionId = false;
3304
102k
  bool IsInvalidMapperModifier = false;
3305
102k
3306
  // Parse '('.
3307
102k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3308
102k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
3309
102k
                         getOpenMPClauseName(Kind).data()))
3310
3.45k
    return true;
3311
98.6k
3312
98.6k
  bool HasIterator = false;
3313
98.6k
  bool NeedRParenForLinear = false;
3314
98.6k
  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
3315
98.6k
                                  tok::annot_pragma_openmp_end);
3316
  // Handle reduction-identifier for reduction clause.
3317
98.6k
  if (Kind == OMPC_reduction || 
Kind == OMPC_task_reduction67.4k
||
3318
66.0k
      Kind == OMPC_in_reduction) {
3319
34.8k
    Data.ExtraModifier = OMPC_REDUCTION_unknown;
3320
34.8k
    if (Kind == OMPC_reduction && 
getLangOpts().OpenMP >= 5031.2k
&&
3321
16.8k
        (Tok.is(tok::identifier) || 
Tok.is(tok::kw_default)14.0k
) &&
3322
2.88k
        NextToken().is(tok::comma)) {
3323
      // Parse optional reduction modifier.
3324
446
      Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3325
446
                                                     getLangOpts().OpenMP);
3326
446
      Data.ExtraModifierLoc = Tok.getLocation();
3327
446
      ConsumeToken();
3328
446
      assert(Tok.is(tok::comma) && "Expected comma.");
3329
446
      (void)ConsumeToken();
3330
446
    }
3331
34.8k
    ColonProtectionRAIIObject ColonRAII(*this);
3332
34.8k
    if (getLangOpts().CPlusPlus)
3333
34.5k
      ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3334
34.5k
                                     /*ObjectType=*/nullptr,
3335
34.5k
                                     /*ObjectHadErrors=*/false,
3336
34.5k
                                     /*EnteringContext=*/false);
3337
34.8k
    InvalidReductionId = ParseReductionId(
3338
34.8k
        *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
3339
34.8k
    if (InvalidReductionId) {
3340
3.02k
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3341
3.02k
                StopBeforeMatch);
3342
3.02k
    }
3343
34.8k
    if (Tok.is(tok::colon))
3344
30.3k
      Data.ColonLoc = ConsumeToken();
3345
4.49k
    else
3346
4.49k
      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
3347
34.8k
    if (!InvalidReductionId)
3348
31.7k
      Data.ReductionOrMapperId =
3349
31.7k
          Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3350
63.8k
  } else if (Kind == OMPC_depend) {
3351
4.20k
    if (getLangOpts().OpenMP >= 50) {
3352
2.67k
      if (Tok.is(tok::identifier) && 
PP.getSpelling(Tok) == "iterator"2.59k
) {
3353
        // Handle optional dependence modifier.
3354
        // iterator(iterators-definition)
3355
        // where iterators-definition is iterator-specifier [,
3356
        // iterators-definition ]
3357
        // where iterator-specifier is [ iterator-type ] identifier =
3358
        // range-specification
3359
40
        HasIterator = true;
3360
40
        EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3361
40
        ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
3362
40
        Data.DepModOrTailExpr = IteratorRes.get();
3363
        // Parse ','
3364
40
        ExpectAndConsume(tok::comma);
3365
40
      }
3366
2.67k
    }
3367
    // Handle dependency type for depend clause.
3368
4.20k
    ColonProtectionRAIIObject ColonRAII(*this);
3369
4.20k
    Data.ExtraModifier = getOpenMPSimpleClauseType(
3370
4.04k
        Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : 
""160
,
3371
4.20k
        getLangOpts().OpenMP);
3372
4.20k
    Data.ExtraModifierLoc = Tok.getLocation();
3373
4.20k
    if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
3374
248
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3375
248
                StopBeforeMatch);
3376
3.96k
    } else {
3377
3.96k
      ConsumeToken();
3378
      // Special processing for depend(source) clause.
3379
3.96k
      if (DKind == OMPD_ordered && 
Data.ExtraModifier == OMPC_DEPEND_source401
) {
3380
        // Parse ')'.
3381
163
        T.consumeClose();
3382
163
        return false;
3383
163
      }
3384
4.04k
    }
3385
4.04k
    if (Tok.is(tok::colon)) {
3386
3.66k
      Data.ColonLoc = ConsumeToken();
3387
380
    } else {
3388
24
      Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3389
356
                                      : diag::warn_pragma_expected_colon)
3390
380
          << "dependency type";
3391
380
    }
3392
59.6k
  } else if (Kind == OMPC_linear) {
3393
    // Try to parse modifier if any.
3394
3.20k
    Data.ExtraModifier = OMPC_LINEAR_val;
3395
3.20k
    if (Tok.is(tok::identifier) && 
PP.LookAhead(0).is(tok::l_paren)2.88k
) {
3396
298
      Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3397
298
                                                     getLangOpts().OpenMP);
3398
298
      Data.ExtraModifierLoc = ConsumeToken();
3399
298
      LinearT.consumeOpen();
3400
298
      NeedRParenForLinear = true;
3401
298
    }
3402
56.4k
  } else if (Kind == OMPC_lastprivate) {
3403
    // Try to parse modifier if any.
3404
7.40k
    Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3405
    // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3406
    // distribute and taskloop based directives.
3407
7.40k
    if ((getLangOpts().OpenMP >= 50 && 
!isOpenMPDistributeDirective(DKind)4.28k
&&
3408
2.41k
         !isOpenMPTaskLoopDirective(DKind)) &&
3409
1.49k
        Tok.is(tok::identifier) && 
PP.LookAhead(0).is(tok::colon)1.25k
) {
3410
92
      Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3411
92
                                                     getLangOpts().OpenMP);
3412
92
      Data.ExtraModifierLoc = Tok.getLocation();
3413
92
      ConsumeToken();
3414
92
      assert(Tok.is(tok::colon) && "Expected colon.");
3415
92
      Data.ColonLoc = ConsumeToken();
3416
92
    }
3417
49.0k
  } else if (Kind == OMPC_map) {
3418
    // Handle map type for map clause.
3419
17.4k
    ColonProtectionRAIIObject ColonRAII(*this);
3420
17.4k
3421
    // The first identifier may be a list item, a map-type or a
3422
    // map-type-modifier. The map-type can also be delete which has the same
3423
    // spelling of the C++ delete keyword.
3424
17.4k
    Data.ExtraModifier = OMPC_MAP_unknown;
3425
17.4k
    Data.ExtraModifierLoc = Tok.getLocation();
3426
17.4k
3427
    // Check for presence of a colon in the map clause.
3428
17.4k
    TentativeParsingAction TPA(*this);
3429
17.4k
    bool ColonPresent = false;
3430
17.4k
    if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3431
17.4k
        StopBeforeMatch)) {
3432
17.4k
      if (Tok.is(tok::colon))
3433
7.68k
        ColonPresent = true;
3434
17.4k
    }
3435
17.4k
    TPA.Revert();
3436
    // Only parse map-type-modifier[s] and map-type if a colon is present in
3437
    // the map clause.
3438
17.4k
    if (ColonPresent) {
3439
7.68k
      IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3440
7.68k
      if (!IsInvalidMapperModifier)
3441
7.66k
        parseMapType(*this, Data);
3442
20
      else
3443
20
        SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
3444
7.68k
    }
3445
17.4k
    if (Data.ExtraModifier == OMPC_MAP_unknown) {
3446
10.3k
      Data.ExtraModifier = OMPC_MAP_tofrom;
3447
10.3k
      Data.IsMapTypeImplicit = true;
3448
10.3k
    }
3449
17.4k
3450
17.4k
    if (Tok.is(tok::colon))
3451
7.68k
      Data.ColonLoc = ConsumeToken();
3452
31.6k
  } else if (Kind == OMPC_to || 
Kind == OMPC_from29.6k
) {
3453
3.03k
    while (Tok.is(tok::identifier)) {
3454
2.40k
      auto Modifier =
3455
2.40k
          static_cast<OpenMPMotionModifierKind>(getOpenMPSimpleClauseType(
3456
2.40k
              Kind, PP.getSpelling(Tok), getLangOpts().OpenMP));
3457
2.40k
      if (Modifier == OMPC_MOTION_MODIFIER_unknown)
3458
1.94k
        break;
3459
460
      Data.MotionModifiers.push_back(Modifier);
3460
460
      Data.MotionModifiersLoc.push_back(Tok.getLocation());
3461
460
      ConsumeToken();
3462
460
      if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
3463
376
        IsInvalidMapperModifier = parseMapperModifier(Data);
3464
376
        if (IsInvalidMapperModifier)
3465
104
          break;
3466
356
      }
3467
      // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
3468
356
      if (getLangOpts().OpenMP < 51)
3469
208
        break;
3470
      // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
3471
      // TODO: Is that intentional?
3472
148
      if (Tok.is(tok::comma))
3473
44
        ConsumeToken();
3474
148
    }
3475
2.88k
    if (!Data.MotionModifiers.empty() && 
Tok.isNot(tok::colon)416
) {
3476
88
      if (!IsInvalidMapperModifier) {
3477
56
        if (getLangOpts().OpenMP < 51)
3478
44
          Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3479
12
        else
3480
12
          Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
3481
56
      }
3482
88
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3483
88
                StopBeforeMatch);
3484
88
    }
3485
    // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
3486
    // that intentional?
3487
2.88k
    if ((!Data.MotionModifiers.empty() || 
getLangOpts().OpenMP >= 512.47k
) &&
3488
480
        Tok.is(tok::colon))
3489
372
      Data.ColonLoc = ConsumeToken();
3490
28.7k
  } else if (Kind == OMPC_allocate ||
3491
27.0k
             (Kind == OMPC_affinity && 
Tok.is(tok::identifier)112
&&
3492
1.66k
              
PP.getSpelling(Tok) == "iterator"88
)) {
3493
    // Handle optional allocator expression followed by colon delimiter.
3494
1.66k
    ColonProtectionRAIIObject ColonRAII(*this);
3495
1.66k
    TentativeParsingAction TPA(*this);
3496
    // OpenMP 5.0, 2.10.1, task Construct.
3497
    // where aff-modifier is one of the following:
3498
    // iterator(iterators-definition)
3499
1.66k
    ExprResult Tail;
3500
1.66k
    if (Kind == OMPC_allocate) {
3501
1.63k
      Tail = ParseAssignmentExpression();
3502
26
    } else {
3503
26
      HasIterator = true;
3504
26
      EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3505
26
      Tail = ParseOpenMPIteratorsExpr();
3506
26
    }
3507
1.66k
    Tail = Actions.CorrectDelayedTyposInExpr(Tail);
3508
1.66k
    Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3509
1.66k
                                       /*DiscardedValue=*/false);
3510
1.66k
    if (Tail.isUsable()) {
3511
919
      if (Tok.is(tok::colon)) {
3512
493
        Data.DepModOrTailExpr = Tail.get();
3513
493
        Data.ColonLoc = ConsumeToken();
3514
493
        TPA.Commit();
3515
426
      } else {
3516
        // Colon not found, parse only list of variables.
3517
426
        TPA.Revert();
3518
426
      }
3519
743
    } else {
3520
      // Parsing was unsuccessfull, revert and skip to the end of clause or
3521
      // directive.
3522
743
      TPA.Revert();
3523
743
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3524
743
                StopBeforeMatch);
3525
743
    }
3526
1.66k
  }
3527
98.6k
3528
98.4k
  bool IsComma =
3529
98.4k
      (Kind != OMPC_reduction && 
Kind != OMPC_task_reduction67.2k
&&
3530
65.8k
       Kind != OMPC_in_reduction && 
Kind != OMPC_depend63.6k
&&
Kind != OMPC_map59.6k
) ||
3531
56.2k
      (Kind == OMPC_reduction && 
!InvalidReductionId31.2k
) ||
3532
27.8k
      (Kind == OMPC_map && 
Data.ExtraModifier != OMPC_MAP_unknown17.4k
) ||
3533
10.4k
      (Kind == OMPC_depend && 
Data.ExtraModifier != OMPC_DEPEND_unknown4.04k
);
3534
98.4k
  const bool MayHaveTail = (Kind == OMPC_linear || 
Kind == OMPC_aligned95.2k
);
3535
226k
  while (IsComma || 
(102k
Tok.isNot(tok::r_paren)102k
&&
Tok.isNot(tok::colon)14.5k
&&
3536
128k
                     
Tok.isNot(tok::annot_pragma_openmp_end)12.2k
)) {
3537
128k
    ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
3538
128k
    ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3539
    // Parse variable
3540
128k
    ExprResult VarExpr =
3541
128k
        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3542
128k
    if (VarExpr.isUsable()) {
3543
114k
      Vars.push_back(VarExpr.get());
3544
14.0k
    } else {
3545
14.0k
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3546
14.0k
                StopBeforeMatch);
3547
14.0k
    }
3548
    // Skip ',' if any
3549
128k
    IsComma = Tok.is(tok::comma);
3550
128k
    if (IsComma)
3551
32.5k
      ConsumeToken();
3552
95.9k
    else if (Tok.isNot(tok::r_paren) &&
3553
9.75k
             Tok.isNot(tok::annot_pragma_openmp_end) &&
3554
2.67k
             (!MayHaveTail || 
Tok.isNot(tok::colon)2.06k
))
3555
608
      Diag(Tok, diag::err_omp_expected_punc)
3556
0
          << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3557
608
                                   : getOpenMPClauseName(Kind))
3558
608
          << (Kind == OMPC_flush);
3559
128k
  }
3560
98.4k
3561
  // Parse ')' for linear clause with modifier.
3562
98.4k
  if (NeedRParenForLinear)
3563
298
    LinearT.consumeClose();
3564
98.4k
3565
  // Parse ':' linear-step (or ':' alignment).
3566
98.4k
  const bool MustHaveTail = MayHaveTail && 
Tok.is(tok::colon)5.55k
;
3567
98.4k
  if (MustHaveTail) {
3568
2.15k
    Data.ColonLoc = Tok.getLocation();
3569
2.15k
    SourceLocation ELoc = ConsumeToken();
3570
2.15k
    ExprResult Tail = ParseAssignmentExpression();
3571
2.15k
    Tail =
3572
2.15k
        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
3573
2.15k
    if (Tail.isUsable())
3574
2.08k
      Data.DepModOrTailExpr = Tail.get();
3575
72
    else
3576
72
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3577
72
                StopBeforeMatch);
3578
2.15k
  }
3579
98.4k
3580
  // Parse ')'.
3581
98.4k
  Data.RLoc = Tok.getLocation();
3582
98.4k
  if (!T.consumeClose())
3583
89.9k
    Data.RLoc = T.getCloseLocation();
3584
  // Exit from scope when the iterator is used in depend clause.
3585
98.4k
  if (HasIterator)
3586
66
    ExitScope();
3587
98.4k
  return (Kind != OMPC_depend && 
Kind != OMPC_map94.4k
&&
Vars.empty()77.0k
) ||
3588
87.6k
         (MustHaveTail && 
!Data.DepModOrTailExpr2.15k
) ||
InvalidReductionId87.5k
||
3589
87.1k
         IsInvalidMapperModifier;
3590
98.6k
}
3591
3592
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
3593
/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
3594
/// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
3595
///
3596
///    private-clause:
3597
///       'private' '(' list ')'
3598
///    firstprivate-clause:
3599
///       'firstprivate' '(' list ')'
3600
///    lastprivate-clause:
3601
///       'lastprivate' '(' list ')'
3602
///    shared-clause:
3603
///       'shared' '(' list ')'
3604
///    linear-clause:
3605
///       'linear' '(' linear-list [ ':' linear-step ] ')'
3606
///    aligned-clause:
3607
///       'aligned' '(' list [ ':' alignment ] ')'
3608
///    reduction-clause:
3609
///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
3610
///    task_reduction-clause:
3611
///       'task_reduction' '(' reduction-identifier ':' list ')'
3612
///    in_reduction-clause:
3613
///       'in_reduction' '(' reduction-identifier ':' list ')'
3614
///    copyprivate-clause:
3615
///       'copyprivate' '(' list ')'
3616
///    flush-clause:
3617
///       'flush' '(' list ')'
3618
///    depend-clause:
3619
///       'depend' '(' in | out | inout : list | source ')'
3620
///    map-clause:
3621
///       'map' '(' [ [ always [,] ] [ close [,] ]
3622
///          [ mapper '(' mapper-identifier ')' [,] ]
3623
///          to | from | tofrom | alloc | release | delete ':' ] list ')';
3624
///    to-clause:
3625
///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3626
///    from-clause:
3627
///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3628
///    use_device_ptr-clause:
3629
///       'use_device_ptr' '(' list ')'
3630
///    use_device_addr-clause:
3631
///       'use_device_addr' '(' list ')'
3632
///    is_device_ptr-clause:
3633
///       'is_device_ptr' '(' list ')'
3634
///    allocate-clause:
3635
///       'allocate' '(' [ allocator ':' ] list ')'
3636
///    nontemporal-clause:
3637
///       'nontemporal' '(' list ')'
3638
///    inclusive-clause:
3639
///       'inclusive' '(' list ')'
3640
///    exclusive-clause:
3641
///       'exclusive' '(' list ')'
3642
///
3643
/// For 'linear' clause linear-list may have the following forms:
3644
///  list
3645
///  modifier(list)
3646
/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
3647
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
3648
                                            OpenMPClauseKind Kind,
3649
101k
                                            bool ParseOnly) {
3650
101k
  SourceLocation Loc = Tok.getLocation();
3651
101k
  SourceLocation LOpen = ConsumeToken();
3652
101k
  SmallVector<Expr *, 4> Vars;
3653
101k
  OpenMPVarListDataTy Data;
3654
101k
3655
101k
  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
3656
14.8k
    return nullptr;
3657
86.8k
3658
86.8k
  if (ParseOnly)
3659
569
    return nullptr;
3660
86.3k
  OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
3661
86.3k
  return Actions.ActOnOpenMPVarListClause(
3662
86.3k
      Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
3663
86.3k
      Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
3664
86.3k
      Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
3665
86.3k
      Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
3666
86.3k
      Data.MotionModifiersLoc);
3667
86.3k
}
3668