Coverage Report

Created: 2020-11-24 06:42

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