Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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/StmtOpenMP.h"
15
#include "clang/Parse/ParseDiagnostic.h"
16
#include "clang/Parse/Parser.h"
17
#include "clang/Parse/RAIIObjectsForParser.h"
18
#include "clang/Sema/Scope.h"
19
#include "llvm/ADT/PointerIntPair.h"
20
21
using namespace clang;
22
23
//===----------------------------------------------------------------------===//
24
// OpenMP declarative directives.
25
//===----------------------------------------------------------------------===//
26
27
namespace {
28
enum OpenMPDirectiveKindEx {
29
  OMPD_cancellation = OMPD_unknown + 1,
30
  OMPD_data,
31
  OMPD_declare,
32
  OMPD_end,
33
  OMPD_end_declare,
34
  OMPD_enter,
35
  OMPD_exit,
36
  OMPD_point,
37
  OMPD_reduction,
38
  OMPD_target_enter,
39
  OMPD_target_exit,
40
  OMPD_update,
41
  OMPD_distribute_parallel,
42
  OMPD_teams_distribute_parallel,
43
  OMPD_target_teams_distribute_parallel,
44
  OMPD_mapper,
45
};
46
47
class DeclDirectiveListParserHelper final {
48
  SmallVector<Expr *, 4> Identifiers;
49
  Parser *P;
50
  OpenMPDirectiveKind Kind;
51
52
public:
53
  DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
54
2.07k
      : P(P), Kind(Kind) {}
55
2.22k
  void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
56
2.22k
    ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
57
2.22k
        P->getCurScope(), SS, NameInfo, Kind);
58
2.22k
    if (Res.isUsable())
59
2.12k
      Identifiers.push_back(Res.get());
60
2.22k
  }
61
1.99k
  llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
62
};
63
} // namespace
64
65
// Map token string to extended OMP token kind that are
66
// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
67
483k
static unsigned getOpenMPDirectiveKindEx(StringRef S) {
68
483k
  auto DKind = getOpenMPDirectiveKind(S);
69
483k
  if (DKind != OMPD_unknown)
70
397k
    return DKind;
71
85.7k
72
85.7k
  return llvm::StringSwitch<unsigned>(S)
73
85.7k
      .Case("cancellation", OMPD_cancellation)
74
85.7k
      .Case("data", OMPD_data)
75
85.7k
      .Case("declare", OMPD_declare)
76
85.7k
      .Case("end", OMPD_end)
77
85.7k
      .Case("enter", OMPD_enter)
78
85.7k
      .Case("exit", OMPD_exit)
79
85.7k
      .Case("point", OMPD_point)
80
85.7k
      .Case("reduction", OMPD_reduction)
81
85.7k
      .Case("update", OMPD_update)
82
85.7k
      .Case("mapper", OMPD_mapper)
83
85.7k
      .Default(OMPD_unknown);
84
85.7k
}
85
86
123k
static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
87
123k
  // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
88
123k
  // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
89
123k
  // TODO: add other combined directives in topological order.
90
123k
  static const unsigned F[][3] = {
91
123k
      {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
92
123k
      {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
93
123k
      {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
94
123k
      {OMPD_declare, OMPD_simd, OMPD_declare_simd},
95
123k
      {OMPD_declare, OMPD_target, OMPD_declare_target},
96
123k
      {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
97
123k
      {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
98
123k
      {OMPD_distribute_parallel_for, OMPD_simd,
99
123k
       OMPD_distribute_parallel_for_simd},
100
123k
      {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
101
123k
      {OMPD_end, OMPD_declare, OMPD_end_declare},
102
123k
      {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
103
123k
      {OMPD_target, OMPD_data, OMPD_target_data},
104
123k
      {OMPD_target, OMPD_enter, OMPD_target_enter},
105
123k
      {OMPD_target, OMPD_exit, OMPD_target_exit},
106
123k
      {OMPD_target, OMPD_update, OMPD_target_update},
107
123k
      {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
108
123k
      {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
109
123k
      {OMPD_for, OMPD_simd, OMPD_for_simd},
110
123k
      {OMPD_parallel, OMPD_for, OMPD_parallel_for},
111
123k
      {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
112
123k
      {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
113
123k
      {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
114
123k
      {OMPD_target, OMPD_parallel, OMPD_target_parallel},
115
123k
      {OMPD_target, OMPD_simd, OMPD_target_simd},
116
123k
      {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
117
123k
      {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
118
123k
      {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
119
123k
      {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
120
123k
      {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
121
123k
      {OMPD_teams_distribute_parallel, OMPD_for,
122
123k
       OMPD_teams_distribute_parallel_for},
123
123k
      {OMPD_teams_distribute_parallel_for, OMPD_simd,
124
123k
       OMPD_teams_distribute_parallel_for_simd},
125
123k
      {OMPD_target, OMPD_teams, OMPD_target_teams},
126
123k
      {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
127
123k
      {OMPD_target_teams_distribute, OMPD_parallel,
128
123k
       OMPD_target_teams_distribute_parallel},
129
123k
      {OMPD_target_teams_distribute, OMPD_simd,
130
123k
       OMPD_target_teams_distribute_simd},
131
123k
      {OMPD_target_teams_distribute_parallel, OMPD_for,
132
123k
       OMPD_target_teams_distribute_parallel_for},
133
123k
      {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
134
123k
       OMPD_target_teams_distribute_parallel_for_simd}};
135
123k
  enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
136
123k
  Token Tok = P.getCurToken();
137
123k
  unsigned DKind =
138
123k
      Tok.isAnnotation()
139
123k
          ? 
static_cast<unsigned>(OMPD_unknown)114
140
123k
          : 
getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok))123k
;
141
123k
  if (DKind == OMPD_unknown)
142
2.79k
    return OMPD_unknown;
143
120k
144
4.58M
  
for (unsigned I = 0; 120k
I < llvm::array_lengthof(F);
++I4.46M
) {
145
4.46M
    if (DKind != F[I][0])
146
3.95M
      continue;
147
507k
148
507k
    Tok = P.getPreprocessor().LookAhead(0);
149
507k
    unsigned SDKind =
150
507k
        Tok.isAnnotation()
151
507k
            ? 
static_cast<unsigned>(OMPD_unknown)147k
152
507k
            : 
getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok))360k
;
153
507k
    if (SDKind == OMPD_unknown)
154
205k
      continue;
155
302k
156
302k
    if (SDKind == F[I][1]) {
157
127k
      P.ConsumeToken();
158
127k
      DKind = F[I][2];
159
127k
    }
160
302k
  }
161
120k
  return DKind < OMPD_unknown ? 
static_cast<OpenMPDirectiveKind>(DKind)120k
162
120k
                              : 
OMPD_unknown12
;
163
120k
}
164
165
592
static DeclarationName parseOpenMPReductionId(Parser &P) {
166
592
  Token Tok = P.getCurToken();
167
592
  Sema &Actions = P.getActions();
168
592
  OverloadedOperatorKind OOK = OO_None;
169
592
  // Allow to use 'operator' keyword for C++ operators
170
592
  bool WithOperator = false;
171
592
  if (Tok.is(tok::kw_operator)) {
172
48
    P.ConsumeToken();
173
48
    Tok = P.getCurToken();
174
48
    WithOperator = true;
175
48
  }
176
592
  switch (Tok.getKind()) {
177
592
  case tok::plus: // '+'
178
74
    OOK = OO_Plus;
179
74
    break;
180
592
  case tok::minus: // '-'
181
12
    OOK = OO_Minus;
182
12
    break;
183
592
  case tok::star: // '*'
184
8
    OOK = OO_Star;
185
8
    break;
186
592
  case tok::amp: // '&'
187
16
    OOK = OO_Amp;
188
16
    break;
189
592
  case tok::pipe: // '|'
190
8
    OOK = OO_Pipe;
191
8
    break;
192
592
  case tok::caret: // '^'
193
8
    OOK = OO_Caret;
194
8
    break;
195
592
  case tok::ampamp: // '&&'
196
24
    OOK = OO_AmpAmp;
197
24
    break;
198
592
  case tok::pipepipe: // '||'
199
8
    OOK = OO_PipePipe;
200
8
    break;
201
592
  case tok::identifier: // identifier
202
394
    if (!WithOperator)
203
394
      break;
204
0
    LLVM_FALLTHROUGH;
205
40
  default:
206
40
    P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
207
40
    P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
208
40
                Parser::StopBeforeMatch);
209
40
    return DeclarationName();
210
552
  }
211
552
  P.ConsumeToken();
212
552
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
213
552
  return OOK == OO_None ? 
DeclNames.getIdentifier(Tok.getIdentifierInfo())394
214
552
                        : 
DeclNames.getCXXOperatorName(OOK)158
;
215
552
}
216
217
/// Parse 'omp declare reduction' construct.
218
///
219
///       declare-reduction-directive:
220
///        annot_pragma_openmp 'declare' 'reduction'
221
///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
222
///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
223
///        annot_pragma_openmp_end
224
/// <reduction_id> is either a base language identifier or one of the following
225
/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
226
///
227
Parser::DeclGroupPtrTy
228
608
Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
229
608
  // Parse '('.
230
608
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
231
608
  if (T.expectAndConsume(diag::err_expected_lparen_after,
232
608
                         getOpenMPDirectiveName(OMPD_declare_reduction))) {
233
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
234
16
    return DeclGroupPtrTy();
235
16
  }
236
592
237
592
  DeclarationName Name = parseOpenMPReductionId(*this);
238
592
  if (Name.isEmpty() && 
Tok.is(tok::annot_pragma_openmp_end)40
)
239
32
    return DeclGroupPtrTy();
240
560
241
560
  // Consume ':'.
242
560
  bool IsCorrect = !ExpectAndConsume(tok::colon);
243
560
244
560
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)16
)
245
8
    return DeclGroupPtrTy();
246
552
247
552
  IsCorrect = IsCorrect && 
!Name.isEmpty()544
;
248
552
249
552
  if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
250
16
    Diag(Tok.getLocation(), diag::err_expected_type);
251
16
    IsCorrect = false;
252
16
  }
253
552
254
552
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)24
)
255
16
    return DeclGroupPtrTy();
256
536
257
536
  SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
258
536
  // Parse list of types until ':' token.
259
650
  do {
260
650
    ColonProtectionRAIIObject ColonRAII(*this);
261
650
    SourceRange Range;
262
650
    TypeResult TR =
263
650
        ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
264
650
    if (TR.isUsable()) {
265
618
      QualType ReductionType =
266
618
          Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
267
618
      if (!ReductionType.isNull()) {
268
580
        ReductionTypes.push_back(
269
580
            std::make_pair(ReductionType, Range.getBegin()));
270
580
      }
271
618
    } else {
272
32
      SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
273
32
                StopBeforeMatch);
274
32
    }
275
650
276
650
    if (Tok.is(tok::colon) || 
Tok.is(tok::annot_pragma_openmp_end)138
)
277
536
      break;
278
114
279
114
    // Consume ','.
280
114
    if (ExpectAndConsume(tok::comma)) {
281
8
      IsCorrect = false;
282
8
      if (Tok.is(tok::annot_pragma_openmp_end)) {
283
0
        Diag(Tok.getLocation(), diag::err_expected_type);
284
0
        return DeclGroupPtrTy();
285
0
      }
286
114
    }
287
114
  } while (Tok.isNot(tok::annot_pragma_openmp_end));
288
536
289
536
  if (ReductionTypes.empty()) {
290
46
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
291
46
    return DeclGroupPtrTy();
292
46
  }
293
490
294
490
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
295
8
    return DeclGroupPtrTy();
296
482
297
482
  // Consume ':'.
298
482
  if (ExpectAndConsume(tok::colon))
299
8
    IsCorrect = false;
300
482
301
482
  if (Tok.is(tok::annot_pragma_openmp_end)) {
302
32
    Diag(Tok.getLocation(), diag::err_expected_expression);
303
32
    return DeclGroupPtrTy();
304
32
  }
305
450
306
450
  DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
307
450
      getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
308
450
309
450
  // Parse <combiner> expression and then parse initializer if any for each
310
450
  // correct type.
311
450
  unsigned I = 0, E = ReductionTypes.size();
312
532
  for (Decl *D : DRD.get()) {
313
532
    TentativeParsingAction TPA(*this);
314
532
    ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
315
532
                                    Scope::CompoundStmtScope |
316
532
                                    Scope::OpenMPDirectiveScope);
317
532
    // Parse <combiner> expression.
318
532
    Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
319
532
    ExprResult CombinerResult =
320
532
        Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
321
532
                                    D->getLocation(), /*DiscardedValue*/ false);
322
532
    Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
323
532
324
532
    if (CombinerResult.isInvalid() && 
Tok.isNot(tok::r_paren)54
&&
325
532
        
Tok.isNot(tok::annot_pragma_openmp_end)2
) {
326
2
      TPA.Commit();
327
2
      IsCorrect = false;
328
2
      break;
329
2
    }
330
530
    IsCorrect = !T.consumeClose() && IsCorrect && 
CombinerResult.isUsable()514
;
331
530
    ExprResult InitializerResult;
332
530
    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
333
230
      // Parse <initializer> expression.
334
230
      if (Tok.is(tok::identifier) &&
335
230
          
Tok.getIdentifierInfo()->isStr("initializer")214
) {
336
214
        ConsumeToken();
337
214
      } else {
338
16
        Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
339
16
        TPA.Commit();
340
16
        IsCorrect = false;
341
16
        break;
342
16
      }
343
214
      // Parse '('.
344
214
      BalancedDelimiterTracker T(*this, tok::l_paren,
345
214
                                 tok::annot_pragma_openmp_end);
346
214
      IsCorrect =
347
214
          !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
348
214
          
IsCorrect190
;
349
214
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
350
206
        ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
351
206
                                        Scope::CompoundStmtScope |
352
206
                                        Scope::OpenMPDirectiveScope);
353
206
        // Parse expression.
354
206
        VarDecl *OmpPrivParm =
355
206
            Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
356
206
                                                                D);
357
206
        // Check if initializer is omp_priv <init_expr> or something else.
358
206
        if (Tok.is(tok::identifier) &&
359
206
            
Tok.getIdentifierInfo()->isStr("omp_priv")182
) {
360
108
          if (Actions.getLangOpts().CPlusPlus) {
361
88
            InitializerResult = Actions.ActOnFinishFullExpr(
362
88
                ParseAssignmentExpression().get(), D->getLocation(),
363
88
                /*DiscardedValue*/ false);
364
88
          } else {
365
20
            ConsumeToken();
366
20
            ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
367
20
          }
368
108
        } else {
369
98
          InitializerResult = Actions.ActOnFinishFullExpr(
370
98
              ParseAssignmentExpression().get(), D->getLocation(),
371
98
              /*DiscardedValue*/ false);
372
98
        }
373
206
        Actions.ActOnOpenMPDeclareReductionInitializerEnd(
374
206
            D, InitializerResult.get(), OmpPrivParm);
375
206
        if (InitializerResult.isInvalid() && 
Tok.isNot(tok::r_paren)32
&&
376
206
            
Tok.isNot(tok::annot_pragma_openmp_end)16
) {
377
12
          TPA.Commit();
378
12
          IsCorrect = false;
379
12
          break;
380
12
        }
381
194
        IsCorrect =
382
194
            !T.consumeClose() && 
IsCorrect156
&&
!InitializerResult.isInvalid()156
;
383
194
      }
384
214
    }
385
530
386
530
    ++I;
387
502
    // Revert parsing if not the last type, otherwise accept it, we're done with
388
502
    // parsing.
389
502
    if (I != E)
390
82
      TPA.Revert();
391
420
    else
392
420
      TPA.Commit();
393
502
  }
394
450
  return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
395
450
                                                         IsCorrect);
396
450
}
397
398
20
void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
399
20
  // Parse declarator '=' initializer.
400
20
  // If a '==' or '+=' is found, suggest a fixit to '='.
401
20
  if (isTokenEqualOrEqualTypo()) {
402
18
    ConsumeToken();
403
18
404
18
    if (Tok.is(tok::code_completion)) {
405
0
      Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
406
0
      Actions.FinalizeDeclaration(OmpPrivParm);
407
0
      cutOffParsing();
408
0
      return;
409
0
    }
410
18
411
18
    ExprResult Init(ParseInitializer());
412
18
413
18
    if (Init.isInvalid()) {
414
2
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
415
2
      Actions.ActOnInitializerError(OmpPrivParm);
416
16
    } else {
417
16
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
418
16
                                   /*DirectInit=*/false);
419
16
    }
420
18
  } else 
if (2
Tok.is(tok::l_paren)2
) {
421
0
    // Parse C++ direct initializer: '(' expression-list ')'
422
0
    BalancedDelimiterTracker T(*this, tok::l_paren);
423
0
    T.consumeOpen();
424
0
425
0
    ExprVector Exprs;
426
0
    CommaLocsTy CommaLocs;
427
0
428
0
    SourceLocation LParLoc = T.getOpenLocation();
429
0
    auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
430
0
      QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
431
0
          getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
432
0
          OmpPrivParm->getLocation(), Exprs, LParLoc);
433
0
      CalledSignatureHelp = true;
434
0
      return PreferredType;
435
0
    };
436
0
    if (ParseExpressionList(Exprs, CommaLocs, [&] {
437
0
          PreferredType.enterFunctionArgument(Tok.getLocation(),
438
0
                                              RunSignatureHelp);
439
0
        })) {
440
0
      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
441
0
        RunSignatureHelp();
442
0
      Actions.ActOnInitializerError(OmpPrivParm);
443
0
      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
444
0
    } else {
445
0
      // Match the ')'.
446
0
      SourceLocation RLoc = Tok.getLocation();
447
0
      if (!T.consumeClose())
448
0
        RLoc = T.getCloseLocation();
449
0
450
0
      assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451
0
             "Unexpected number of commas!");
452
0
453
0
      ExprResult Initializer =
454
0
          Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
455
0
      Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
456
0
                                   /*DirectInit=*/true);
457
0
    }
458
2
  } else if (getLangOpts().CPlusPlus11 && 
Tok.is(tok::l_brace)0
) {
459
0
    // Parse C++0x braced-init-list.
460
0
    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
461
0
462
0
    ExprResult Init(ParseBraceInitializer());
463
0
464
0
    if (Init.isInvalid()) {
465
0
      Actions.ActOnInitializerError(OmpPrivParm);
466
0
    } else {
467
0
      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
468
0
                                   /*DirectInit=*/true);
469
0
    }
470
2
  } else {
471
2
    Actions.ActOnUninitializedDecl(OmpPrivParm);
472
2
  }
473
20
}
474
475
/// Parses 'omp declare mapper' directive.
476
///
477
///       declare-mapper-directive:
478
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
479
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
480
///         annot_pragma_openmp_end
481
/// <mapper-identifier> and <var> are base language identifiers.
482
///
483
Parser::DeclGroupPtrTy
484
292
Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
485
292
  bool IsCorrect = true;
486
292
  // Parse '('
487
292
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
488
292
  if (T.expectAndConsume(diag::err_expected_lparen_after,
489
292
                         getOpenMPDirectiveName(OMPD_declare_mapper))) {
490
16
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
491
16
    return DeclGroupPtrTy();
492
16
  }
493
276
494
276
  // Parse <mapper-identifier>
495
276
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
496
276
  DeclarationName MapperId;
497
276
  if (PP.LookAhead(0).is(tok::colon)) {
498
204
    if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)36
) {
499
8
      Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
500
8
      IsCorrect = false;
501
196
    } else {
502
196
      MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
503
196
    }
504
204
    ConsumeToken();
505
204
    // Consume ':'.
506
204
    ExpectAndConsume(tok::colon);
507
204
  } else {
508
72
    // If no mapper identifier is provided, its name is "default" by default
509
72
    MapperId =
510
72
        DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
511
72
  }
512
276
513
276
  if (!IsCorrect && 
Tok.is(tok::annot_pragma_openmp_end)8
)
514
0
    return DeclGroupPtrTy();
515
276
516
276
  // Parse <type> <var>
517
276
  DeclarationName VName;
518
276
  QualType MapperType;
519
276
  SourceRange Range;
520
276
  TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
521
276
  if (ParsedType.isUsable())
522
224
    MapperType =
523
224
        Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
524
276
  if (MapperType.isNull())
525
60
    IsCorrect = false;
526
276
  if (!IsCorrect) {
527
68
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
528
68
    return DeclGroupPtrTy();
529
68
  }
530
208
531
208
  // Consume ')'.
532
208
  IsCorrect &= !T.consumeClose();
533
208
  if (!IsCorrect) {
534
8
    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
535
8
    return DeclGroupPtrTy();
536
8
  }
537
200
538
200
  // Enter scope.
539
200
  OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
540
200
      getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
541
200
      Range.getBegin(), VName, AS);
542
200
  DeclarationNameInfo DirName;
543
200
  SourceLocation Loc = Tok.getLocation();
544
200
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
545
200
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
546
200
  ParseScope OMPDirectiveScope(this, ScopeFlags);
547
200
  Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
548
200
549
200
  // Add the mapper variable declaration.
550
200
  Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
551
200
      DMD, getCurScope(), MapperType, Range.getBegin(), VName);
552
200
553
200
  // Parse map clauses.
554
200
  SmallVector<OMPClause *, 6> Clauses;
555
410
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
556
210
    OpenMPClauseKind CKind = Tok.isAnnotation()
557
210
                                 ? 
OMPC_unknown0
558
210
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
559
210
    Actions.StartOpenMPClause(CKind);
560
210
    OMPClause *Clause =
561
210
        ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
562
210
    if (Clause)
563
192
      Clauses.push_back(Clause);
564
18
    else
565
18
      IsCorrect = false;
566
210
    // Skip ',' if any.
567
210
    if (Tok.is(tok::comma))
568
0
      ConsumeToken();
569
210
    Actions.EndOpenMPClause();
570
210
  }
571
200
  if (Clauses.empty()) {
572
16
    Diag(Tok, diag::err_omp_expected_clause)
573
16
        << getOpenMPDirectiveName(OMPD_declare_mapper);
574
16
    IsCorrect = false;
575
16
  }
576
200
577
200
  // Exit scope.
578
200
  Actions.EndOpenMPDSABlock(nullptr);
579
200
  OMPDirectiveScope.Exit();
580
200
581
200
  DeclGroupPtrTy DGP =
582
200
      Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
583
200
  if (!IsCorrect)
584
26
    return DeclGroupPtrTy();
585
174
  return DGP;
586
174
}
587
588
TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
589
                                                   DeclarationName &Name,
590
276
                                                   AccessSpecifier AS) {
591
276
  // Parse the common declaration-specifiers piece.
592
276
  Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
593
276
  DeclSpec DS(AttrFactory);
594
276
  ParseSpecifierQualifierList(DS, AS, DSC);
595
276
596
276
  // Parse the declarator.
597
276
  DeclaratorContext Context = DeclaratorContext::PrototypeContext;
598
276
  Declarator DeclaratorInfo(DS, Context);
599
276
  ParseDeclarator(DeclaratorInfo);
600
276
  Range = DeclaratorInfo.getSourceRange();
601
276
  if (DeclaratorInfo.getIdentifier() == nullptr) {
602
32
    Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
603
32
    return true;
604
32
  }
605
244
  Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
606
244
607
244
  return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
608
244
}
609
610
namespace {
611
/// RAII that recreates function context for correct parsing of clauses of
612
/// 'declare simd' construct.
613
/// OpenMP, 2.8.2 declare simd Construct
614
/// The expressions appearing in the clauses of this directive are evaluated in
615
/// the scope of the arguments of the function declaration or definition.
616
class FNContextRAII final {
617
  Parser &P;
618
  Sema::CXXThisScopeRAII *ThisScope;
619
  Parser::ParseScope *TempScope;
620
  Parser::ParseScope *FnScope;
621
  bool HasTemplateScope = false;
622
  bool HasFunScope = false;
623
  FNContextRAII() = delete;
624
  FNContextRAII(const FNContextRAII &) = delete;
625
  FNContextRAII &operator=(const FNContextRAII &) = delete;
626
627
public:
628
412
  FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
629
412
    Decl *D = *Ptr.get().begin();
630
412
    NamedDecl *ND = dyn_cast<NamedDecl>(D);
631
412
    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
632
412
    Sema &Actions = P.getActions();
633
412
634
412
    // Allow 'this' within late-parsed attributes.
635
412
    ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
636
412
                                           ND && 
ND->isCXXInstanceMember()410
);
637
412
638
412
    // If the Decl is templatized, add template parameters to scope.
639
412
    HasTemplateScope = D->isTemplateDecl();
640
412
    TempScope =
641
412
        new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
642
412
    if (HasTemplateScope)
643
20
      Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
644
412
645
412
    // If the Decl is on a function, add function parameters to the scope.
646
412
    HasFunScope = D->isFunctionOrFunctionTemplate();
647
412
    FnScope = new Parser::ParseScope(
648
412
        &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
649
412
        HasFunScope);
650
412
    if (HasFunScope)
651
406
      Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
652
412
  }
653
412
  ~FNContextRAII() {
654
412
    if (HasFunScope) {
655
406
      P.getActions().ActOnExitFunctionContext();
656
406
      FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
657
406
    }
658
412
    if (HasTemplateScope)
659
20
      TempScope->Exit();
660
412
    delete FnScope;
661
412
    delete TempScope;
662
412
    delete ThisScope;
663
412
  }
664
};
665
} // namespace
666
667
/// Parses clauses for 'declare simd' directive.
668
///    clause:
669
///      'inbranch' | 'notinbranch'
670
///      'simdlen' '(' <expr> ')'
671
///      { 'uniform' '(' <argument_list> ')' }
672
///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
673
///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
674
static bool parseDeclareSimdClauses(
675
    Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
676
    SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
677
    SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
678
412
    SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
679
412
  SourceRange BSRange;
680
412
  const Token &Tok = P.getCurToken();
681
412
  bool IsError = false;
682
946
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
683
542
    if (Tok.isNot(tok::identifier))
684
6
      break;
685
536
    OMPDeclareSimdDeclAttr::BranchStateTy Out;
686
536
    IdentifierInfo *II = Tok.getIdentifierInfo();
687
536
    StringRef ClauseName = II->getName();
688
536
    // Parse 'inranch|notinbranch' clauses.
689
536
    if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
690
104
      if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && 
BS != Out12
) {
691
4
        P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
692
4
            << ClauseName
693
4
            << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
694
4
        IsError = true;
695
4
      }
696
104
      BS = Out;
697
104
      BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
698
104
      P.ConsumeToken();
699
432
    } else if (ClauseName.equals("simdlen")) {
700
108
      if (SimdLen.isUsable()) {
701
2
        P.Diag(Tok, diag::err_omp_more_one_clause)
702
2
            << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
703
2
        IsError = true;
704
2
      }
705
108
      P.ConsumeToken();
706
108
      SourceLocation RLoc;
707
108
      SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
708
108
      if (SimdLen.isInvalid())
709
18
        IsError = true;
710
324
    } else {
711
324
      OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
712
324
      if (CKind == OMPC_uniform || 
CKind == OMPC_aligned266
||
713
324
          
CKind == OMPC_linear140
) {
714
322
        Parser::OpenMPVarListDataTy Data;
715
322
        SmallVectorImpl<Expr *> *Vars = &Uniforms;
716
322
        if (CKind == OMPC_aligned)
717
126
          Vars = &Aligneds;
718
196
        else if (CKind == OMPC_linear)
719
138
          Vars = &Linears;
720
322
721
322
        P.ConsumeToken();
722
322
        if (P.ParseOpenMPVarList(OMPD_declare_simd,
723
322
                                 getOpenMPClauseKind(ClauseName), *Vars, Data))
724
36
          IsError = true;
725
322
        if (CKind == OMPC_aligned) {
726
126
          Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
727
196
        } else if (CKind == OMPC_linear) {
728
138
          if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
729
138
                                                       Data.DepLinMapLoc))
730
2
            Data.LinKind = OMPC_LINEAR_val;
731
138
          LinModifiers.append(Linears.size() - LinModifiers.size(),
732
138
                              Data.LinKind);
733
138
          Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
734
138
        }
735
322
      } else
736
2
        // TODO: add parsing of other clauses.
737
2
        break;
738
534
    }
739
534
    // Skip ',' if any.
740
534
    if (Tok.is(tok::comma))
741
14
      P.ConsumeToken();
742
534
  }
743
412
  return IsError;
744
412
}
745
746
/// Parse clauses for '#pragma omp declare simd'.
747
Parser::DeclGroupPtrTy
748
Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
749
412
                                   CachedTokens &Toks, SourceLocation Loc) {
750
412
  PP.EnterToken(Tok, /*IsReinject*/ true);
751
412
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
752
412
                      /*IsReinject*/ true);
753
412
  // Consume the previously pushed token.
754
412
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
755
412
756
412
  FNContextRAII FnContext(*this, Ptr);
757
412
  OMPDeclareSimdDeclAttr::BranchStateTy BS =
758
412
      OMPDeclareSimdDeclAttr::BS_Undefined;
759
412
  ExprResult Simdlen;
760
412
  SmallVector<Expr *, 4> Uniforms;
761
412
  SmallVector<Expr *, 4> Aligneds;
762
412
  SmallVector<Expr *, 4> Alignments;
763
412
  SmallVector<Expr *, 4> Linears;
764
412
  SmallVector<unsigned, 4> LinModifiers;
765
412
  SmallVector<Expr *, 4> Steps;
766
412
  bool IsError =
767
412
      parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
768
412
                              Alignments, Linears, LinModifiers, Steps);
769
412
  // Need to check for extra tokens.
770
412
  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
771
8
    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
772
8
        << getOpenMPDirectiveName(OMPD_declare_simd);
773
26
    while (Tok.isNot(tok::annot_pragma_openmp_end))
774
18
      ConsumeAnyToken();
775
8
  }
776
412
  // Skip the last annot_pragma_openmp_end.
777
412
  SourceLocation EndLoc = ConsumeAnnotationToken();
778
412
  if (IsError)
779
54
    return Ptr;
780
358
  return Actions.ActOnOpenMPDeclareSimdDirective(
781
358
      Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
782
358
      LinModifiers, Steps, SourceRange(Loc, EndLoc));
783
358
}
784
785
76
Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
786
76
  // OpenMP 4.5 syntax with list of entities.
787
76
  Sema::NamedDeclSetType SameDirectiveDecls;
788
166
  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
789
96
    OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
790
96
    if (Tok.is(tok::identifier)) {
791
64
      IdentifierInfo *II = Tok.getIdentifierInfo();
792
64
      StringRef ClauseName = II->getName();
793
64
      // Parse 'to|link' clauses.
794
64
      if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
795
4
        Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
796
4
        break;
797
4
      }
798
60
      ConsumeToken();
799
60
    }
800
96
    auto &&Callback = [this, MT, &SameDirectiveDecls](
801
118
        CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
802
118
      Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
803
118
                                           SameDirectiveDecls);
804
118
    };
805
92
    if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
806
92
                                 /*AllowScopeSpecifier=*/true))
807
2
      break;
808
90
809
90
    // Consume optional ','.
810
90
    if (Tok.is(tok::comma))
811
8
      ConsumeToken();
812
90
  }
813
76
  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
814
76
  ConsumeAnyToken();
815
76
  SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
816
76
                               SameDirectiveDecls.end());
817
76
  if (Decls.empty())
818
10
    return DeclGroupPtrTy();
819
66
  return Actions.BuildDeclaratorGroup(Decls);
820
66
}
821
822
void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
823
170
                                               SourceLocation DTLoc) {
824
170
  if (DKind != OMPD_end_declare_target) {
825
4
    Diag(Tok, diag::err_expected_end_declare_target);
826
4
    Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
827
4
    return;
828
4
  }
829
166
  ConsumeAnyToken();
830
166
  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
831
2
    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
832
2
        << getOpenMPDirectiveName(OMPD_end_declare_target);
833
2
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
834
2
  }
835
166
  // Skip the last annot_pragma_openmp_end.
836
166
  ConsumeAnyToken();
837
166
}
838
839
/// Parsing of declarative OpenMP directives.
840
///
841
///       threadprivate-directive:
842
///         annot_pragma_openmp 'threadprivate' simple-variable-list
843
///         annot_pragma_openmp_end
844
///
845
///       allocate-directive:
846
///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
847
///         annot_pragma_openmp_end
848
///
849
///       declare-reduction-directive:
850
///        annot_pragma_openmp 'declare' 'reduction' [...]
851
///        annot_pragma_openmp_end
852
///
853
///       declare-mapper-directive:
854
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
855
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
856
///         annot_pragma_openmp_end
857
///
858
///       declare-simd-directive:
859
///         annot_pragma_openmp 'declare simd' {<clause> [,]}
860
///         annot_pragma_openmp_end
861
///         <function declaration/definition>
862
///
863
///       requires directive:
864
///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
865
///         annot_pragma_openmp_end
866
///
867
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
868
    AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
869
3.34k
    DeclSpec::TST TagType, Decl *Tag) {
870
3.34k
  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
871
3.34k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
872
3.34k
873
3.34k
  SourceLocation Loc = ConsumeAnnotationToken();
874
3.34k
  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
875
3.34k
876
3.34k
  switch (DKind) {
877
3.34k
  case OMPD_threadprivate: {
878
1.37k
    ConsumeToken();
879
1.37k
    DeclDirectiveListParserHelper Helper(this, DKind);
880
1.37k
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
881
1.37k
                                  /*AllowScopeSpecifier=*/true)) {
882
1.33k
      // The last seen token is annot_pragma_openmp_end - need to check for
883
1.33k
      // extra tokens.
884
1.33k
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
885
40
        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
886
40
            << getOpenMPDirectiveName(DKind);
887
40
        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
888
40
      }
889
1.33k
      // Skip the last annot_pragma_openmp_end.
890
1.33k
      ConsumeAnnotationToken();
891
1.33k
      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
892
1.33k
                                                       Helper.getIdentifiers());
893
1.33k
    }
894
40
    break;
895
40
  }
896
392
  case OMPD_allocate: {
897
392
    ConsumeToken();
898
392
    DeclDirectiveListParserHelper Helper(this, DKind);
899
392
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
900
392
                                  /*AllowScopeSpecifier=*/true)) {
901
352
      SmallVector<OMPClause *, 1> Clauses;
902
352
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
903
196
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
904
196
                    OMPC_unknown + 1>
905
196
            FirstClauses(OMPC_unknown + 1);
906
196
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
907
196
          OpenMPClauseKind CKind =
908
196
              Tok.isAnnotation() ? 
OMPC_unknown0
909
196
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
910
196
          Actions.StartOpenMPClause(CKind);
911
196
          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
912
196
                                                !FirstClauses[CKind].getInt());
913
196
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
914
196
                    StopBeforeMatch);
915
196
          FirstClauses[CKind].setInt(true);
916
196
          if (Clause != nullptr)
917
144
            Clauses.push_back(Clause);
918
196
          if (Tok.is(tok::annot_pragma_openmp_end)) {
919
196
            Actions.EndOpenMPClause();
920
196
            break;
921
196
          }
922
0
          // Skip ',' if any.
923
0
          if (Tok.is(tok::comma))
924
0
            ConsumeToken();
925
0
          Actions.EndOpenMPClause();
926
0
        }
927
196
        // The last seen token is annot_pragma_openmp_end - need to check for
928
196
        // extra tokens.
929
196
        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
930
0
          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
931
0
              << getOpenMPDirectiveName(DKind);
932
0
          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
933
0
        }
934
196
      }
935
352
      // Skip the last annot_pragma_openmp_end.
936
352
      ConsumeAnnotationToken();
937
352
      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
938
352
                                                  Clauses);
939
352
    }
940
40
    break;
941
40
  }
942
80
  case OMPD_requires: {
943
80
    SourceLocation StartLoc = ConsumeToken();
944
80
    SmallVector<OMPClause *, 5> Clauses;
945
80
    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
946
80
    FirstClauses(OMPC_unknown + 1);
947
80
    if (Tok.is(tok::annot_pragma_openmp_end)) {
948
1
      Diag(Tok, diag::err_omp_expected_clause)
949
1
          << getOpenMPDirectiveName(OMPD_requires);
950
1
      break;
951
1
    }
952
90
    
while (79
Tok.isNot(tok::annot_pragma_openmp_end)) {
953
90
      OpenMPClauseKind CKind = Tok.isAnnotation()
954
90
                                   ? 
OMPC_unknown0
955
90
                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
956
90
      Actions.StartOpenMPClause(CKind);
957
90
      OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
958
90
                                            !FirstClauses[CKind].getInt());
959
90
      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
960
90
                StopBeforeMatch);
961
90
      FirstClauses[CKind].setInt(true);
962
90
      if (Clause != nullptr)
963
76
        Clauses.push_back(Clause);
964
90
      if (Tok.is(tok::annot_pragma_openmp_end)) {
965
79
        Actions.EndOpenMPClause();
966
79
        break;
967
79
      }
968
11
      // Skip ',' if any.
969
11
      if (Tok.is(tok::comma))
970
10
        ConsumeToken();
971
11
      Actions.EndOpenMPClause();
972
11
    }
973
79
    // Consume final annot_pragma_openmp_end
974
79
    if (Clauses.size() == 0) {
975
7
      Diag(Tok, diag::err_omp_expected_clause)
976
7
          << getOpenMPDirectiveName(OMPD_requires);
977
7
      ConsumeAnnotationToken();
978
7
      return nullptr;
979
7
    }
980
72
    ConsumeAnnotationToken();
981
72
    return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
982
72
  }
983
470
  case OMPD_declare_reduction:
984
470
    ConsumeToken();
985
470
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
986
312
      // The last seen token is annot_pragma_openmp_end - need to check for
987
312
      // extra tokens.
988
312
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
989
38
        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
990
38
            << getOpenMPDirectiveName(OMPD_declare_reduction);
991
84
        while (Tok.isNot(tok::annot_pragma_openmp_end))
992
46
          ConsumeAnyToken();
993
38
      }
994
312
      // Skip the last annot_pragma_openmp_end.
995
312
      ConsumeAnnotationToken();
996
312
      return Res;
997
312
    }
998
158
    break;
999
216
  case OMPD_declare_mapper: {
1000
216
    ConsumeToken();
1001
216
    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1002
100
      // Skip the last annot_pragma_openmp_end.
1003
100
      ConsumeAnnotationToken();
1004
100
      return Res;
1005
100
    }
1006
116
    break;
1007
116
  }
1008
430
  case OMPD_declare_simd: {
1009
430
    // The syntax is:
1010
430
    // { #pragma omp declare simd }
1011
430
    // <function-declaration-or-definition>
1012
430
    //
1013
430
    ConsumeToken();
1014
430
    CachedTokens Toks;
1015
2.84k
    while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1016
2.41k
      Toks.push_back(Tok);
1017
2.41k
      ConsumeAnyToken();
1018
2.41k
    }
1019
430
    Toks.push_back(Tok);
1020
430
    ConsumeAnyToken();
1021
430
1022
430
    DeclGroupPtrTy Ptr;
1023
430
    if (Tok.is(tok::annot_pragma_openmp)) {
1024
218
      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
1025
218
    } else 
if (212
Tok.isNot(tok::r_brace)212
&&
!isEofOrEom()210
) {
1026
208
      // Here we expect to see some function declaration.
1027
208
      if (AS == AS_none) {
1028
156
        assert(TagType == DeclSpec::TST_unspecified);
1029
156
        MaybeParseCXX11Attributes(Attrs);
1030
156
        ParsingDeclSpec PDS(*this);
1031
156
        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1032
156
      } else {
1033
52
        Ptr =
1034
52
            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1035
52
      }
1036
208
    }
1037
430
    if (!Ptr) {
1038
18
      Diag(Loc, diag::err_omp_decl_in_declare_simd);
1039
18
      return DeclGroupPtrTy();
1040
18
    }
1041
412
    return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1042
412
  }
1043
412
  case OMPD_declare_target: {
1044
246
    SourceLocation DTLoc = ConsumeAnyToken();
1045
246
    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1046
76
      return ParseOMPDeclareTargetClauses();
1047
76
    }
1048
170
1049
170
    // Skip the last annot_pragma_openmp_end.
1050
170
    ConsumeAnyToken();
1051
170
1052
170
    if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1053
0
      return DeclGroupPtrTy();
1054
170
1055
170
    llvm::SmallVector<Decl *, 4>  Decls;
1056
170
    DKind = parseOpenMPDirectiveKind(*this);
1057
635
    while (DKind != OMPD_end_declare_target && 
Tok.isNot(tok::eof)469
&&
1058
635
           
Tok.isNot(tok::r_brace)467
) {
1059
465
      DeclGroupPtrTy Ptr;
1060
465
      // Here we expect to see some function declaration.
1061
465
      if (AS == AS_none) {
1062
447
        assert(TagType == DeclSpec::TST_unspecified);
1063
447
        MaybeParseCXX11Attributes(Attrs);
1064
447
        ParsingDeclSpec PDS(*this);
1065
447
        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1066
447
      } else {
1067
18
        Ptr =
1068
18
            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1069
18
      }
1070
465
      if (Ptr) {
1071
460
        DeclGroupRef Ref = Ptr.get();
1072
460
        Decls.append(Ref.begin(), Ref.end());
1073
460
      }
1074
465
      if (Tok.isAnnotation() && 
Tok.is(tok::annot_pragma_openmp)190
) {
1075
190
        TentativeParsingAction TPA(*this);
1076
190
        ConsumeAnnotationToken();
1077
190
        DKind = parseOpenMPDirectiveKind(*this);
1078
190
        if (DKind != OMPD_end_declare_target)
1079
24
          TPA.Revert();
1080
166
        else
1081
166
          TPA.Commit();
1082
190
      }
1083
465
    }
1084
170
1085
170
    ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1086
170
    Actions.ActOnFinishOpenMPDeclareTargetDirective();
1087
170
    return Actions.BuildDeclaratorGroup(Decls);
1088
170
  }
1089
170
  case OMPD_unknown:
1090
8
    Diag(Tok, diag::err_omp_unknown_directive);
1091
8
    break;
1092
170
  case OMPD_parallel:
1093
130
  case OMPD_simd:
1094
130
  case OMPD_task:
1095
130
  case OMPD_taskyield:
1096
130
  case OMPD_barrier:
1097
130
  case OMPD_taskwait:
1098
130
  case OMPD_taskgroup:
1099
130
  case OMPD_flush:
1100
130
  case OMPD_for:
1101
130
  case OMPD_for_simd:
1102
130
  case OMPD_sections:
1103
130
  case OMPD_section:
1104
130
  case OMPD_single:
1105
130
  case OMPD_master:
1106
130
  case OMPD_ordered:
1107
130
  case OMPD_critical:
1108
130
  case OMPD_parallel_for:
1109
130
  case OMPD_parallel_for_simd:
1110
130
  case OMPD_parallel_sections:
1111
130
  case OMPD_atomic:
1112
130
  case OMPD_target:
1113
130
  case OMPD_teams:
1114
130
  case OMPD_cancellation_point:
1115
130
  case OMPD_cancel:
1116
130
  case OMPD_target_data:
1117
130
  case OMPD_target_enter_data:
1118
130
  case OMPD_target_exit_data:
1119
130
  case OMPD_target_parallel:
1120
130
  case OMPD_target_parallel_for:
1121
130
  case OMPD_taskloop:
1122
130
  case OMPD_taskloop_simd:
1123
130
  case OMPD_distribute:
1124
130
  case OMPD_end_declare_target:
1125
130
  case OMPD_target_update:
1126
130
  case OMPD_distribute_parallel_for:
1127
130
  case OMPD_distribute_parallel_for_simd:
1128
130
  case OMPD_distribute_simd:
1129
130
  case OMPD_target_parallel_for_simd:
1130
130
  case OMPD_target_simd:
1131
130
  case OMPD_teams_distribute:
1132
130
  case OMPD_teams_distribute_simd:
1133
130
  case OMPD_teams_distribute_parallel_for_simd:
1134
130
  case OMPD_teams_distribute_parallel_for:
1135
130
  case OMPD_target_teams:
1136
130
  case OMPD_target_teams_distribute:
1137
130
  case OMPD_target_teams_distribute_parallel_for:
1138
130
  case OMPD_target_teams_distribute_parallel_for_simd:
1139
130
  case OMPD_target_teams_distribute_simd:
1140
130
    Diag(Tok, diag::err_omp_unexpected_directive)
1141
130
        << 1 << getOpenMPDirectiveName(DKind);
1142
130
    break;
1143
493
  }
1144
745
  
while (493
Tok.isNot(tok::annot_pragma_openmp_end))
1145
252
    ConsumeAnyToken();
1146
493
  ConsumeAnyToken();
1147
493
  return nullptr;
1148
493
}
1149
1150
/// Parsing of declarative or executable OpenMP directives.
1151
///
1152
///       threadprivate-directive:
1153
///         annot_pragma_openmp 'threadprivate' simple-variable-list
1154
///         annot_pragma_openmp_end
1155
///
1156
///       allocate-directive:
1157
///         annot_pragma_openmp 'allocate' simple-variable-list
1158
///         annot_pragma_openmp_end
1159
///
1160
///       declare-reduction-directive:
1161
///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1162
///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1163
///         ('omp_priv' '=' <expression>|<function_call>) ')']
1164
///         annot_pragma_openmp_end
1165
///
1166
///       declare-mapper-directive:
1167
///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1168
///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1169
///         annot_pragma_openmp_end
1170
///
1171
///       executable-directive:
1172
///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1173
///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1174
///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1175
///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1176
///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1177
///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1178
///         'distribute' | 'target enter data' | 'target exit data' |
1179
///         'target parallel' | 'target parallel for' |
1180
///         'target update' | 'distribute parallel for' |
1181
///         'distribute paralle for simd' | 'distribute simd' |
1182
///         'target parallel for simd' | 'target simd' |
1183
///         'teams distribute' | 'teams distribute simd' |
1184
///         'teams distribute parallel for simd' |
1185
///         'teams distribute parallel for' | 'target teams' |
1186
///         'target teams distribute' |
1187
///         'target teams distribute parallel for' |
1188
///         'target teams distribute parallel for simd' |
1189
///         'target teams distribute simd' {clause}
1190
///         annot_pragma_openmp_end
1191
///
1192
StmtResult
1193
114k
Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1194
114k
  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1195
114k
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1196
114k
  SmallVector<OMPClause *, 5> Clauses;
1197
114k
  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1198
114k
  FirstClauses(OMPC_unknown + 1);
1199
114k
  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1200
114k
                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1201
114k
  SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1202
114k
  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1203
114k
  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1204
114k
  // Name of critical directive.
1205
114k
  DeclarationNameInfo DirName;
1206
114k
  StmtResult Directive = StmtError();
1207
114k
  bool HasAssociatedStatement = true;
1208
114k
  bool FlushHasClause = false;
1209
114k
1210
114k
  switch (DKind) {
1211
114k
  case OMPD_threadprivate: {
1212
176
    // FIXME: Should this be permitted in C++?
1213
176
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1214
176
        ParsedStmtContext()) {
1215
4
      Diag(Tok, diag::err_omp_immediate_directive)
1216
4
          << getOpenMPDirectiveName(DKind) << 0;
1217
4
    }
1218
176
    ConsumeToken();
1219
176
    DeclDirectiveListParserHelper Helper(this, DKind);
1220
176
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1221
176
                                  /*AllowScopeSpecifier=*/false)) {
1222
172
      // The last seen token is annot_pragma_openmp_end - need to check for
1223
172
      // extra tokens.
1224
172
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1225
4
        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1226
4
            << getOpenMPDirectiveName(DKind);
1227
4
        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1228
4
      }
1229
172
      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1230
172
          Loc, Helper.getIdentifiers());
1231
172
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1232
172
    }
1233
176
    SkipUntil(tok::annot_pragma_openmp_end);
1234
176
    break;
1235
114k
  }
1236
114k
  case OMPD_allocate: {
1237
138
    // FIXME: Should this be permitted in C++?
1238
138
    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1239
138
        ParsedStmtContext()) {
1240
4
      Diag(Tok, diag::err_omp_immediate_directive)
1241
4
          << getOpenMPDirectiveName(DKind) << 0;
1242
4
    }
1243
138
    ConsumeToken();
1244
138
    DeclDirectiveListParserHelper Helper(this, DKind);
1245
138
    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1246
138
                                  /*AllowScopeSpecifier=*/false)) {
1247
134
      SmallVector<OMPClause *, 1> Clauses;
1248
134
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1249
60
        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1250
60
                    OMPC_unknown + 1>
1251
60
            FirstClauses(OMPC_unknown + 1);
1252
60
        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1253
60
          OpenMPClauseKind CKind =
1254
60
              Tok.isAnnotation() ? 
OMPC_unknown0
1255
60
                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
1256
60
          Actions.StartOpenMPClause(CKind);
1257
60
          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1258
60
                                                !FirstClauses[CKind].getInt());
1259
60
          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1260
60
                    StopBeforeMatch);
1261
60
          FirstClauses[CKind].setInt(true);
1262
60
          if (Clause != nullptr)
1263
56
            Clauses.push_back(Clause);
1264
60
          if (Tok.is(tok::annot_pragma_openmp_end)) {
1265
60
            Actions.EndOpenMPClause();
1266
60
            break;
1267
60
          }
1268
0
          // Skip ',' if any.
1269
0
          if (Tok.is(tok::comma))
1270
0
            ConsumeToken();
1271
0
          Actions.EndOpenMPClause();
1272
0
        }
1273
60
        // The last seen token is annot_pragma_openmp_end - need to check for
1274
60
        // extra tokens.
1275
60
        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1276
0
          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1277
0
              << getOpenMPDirectiveName(DKind);
1278
0
          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1279
0
        }
1280
60
      }
1281
134
      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1282
134
          Loc, Helper.getIdentifiers(), Clauses);
1283
134
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1284
134
    }
1285
138
    SkipUntil(tok::annot_pragma_openmp_end);
1286
138
    break;
1287
114k
  }
1288
114k
  case OMPD_declare_reduction:
1289
138
    ConsumeToken();
1290
138
    if (DeclGroupPtrTy Res =
1291
138
            ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1292
138
      // The last seen token is annot_pragma_openmp_end - need to check for
1293
138
      // extra tokens.
1294
138
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1295
2
        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1296
2
            << getOpenMPDirectiveName(OMPD_declare_reduction);
1297
10
        while (Tok.isNot(tok::annot_pragma_openmp_end))
1298
8
          ConsumeAnyToken();
1299
2
      }
1300
138
      ConsumeAnyToken();
1301
138
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1302
138
    } else {
1303
0
      SkipUntil(tok::annot_pragma_openmp_end);
1304
0
    }
1305
138
    break;
1306
114k
  case OMPD_declare_mapper: {
1307
76
    ConsumeToken();
1308
76
    if (DeclGroupPtrTy Res =
1309
74
            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1310
74
      // Skip the last annot_pragma_openmp_end.
1311
74
      ConsumeAnnotationToken();
1312
74
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1313
74
    } else {
1314
2
      SkipUntil(tok::annot_pragma_openmp_end);
1315
2
    }
1316
76
    break;
1317
114k
  }
1318
114k
  case OMPD_flush:
1319
274
    if (PP.LookAhead(0).is(tok::l_paren)) {
1320
44
      FlushHasClause = true;
1321
44
      // Push copy of the current token back to stream to properly parse
1322
44
      // pseudo-clause OMPFlushClause.
1323
44
      PP.EnterToken(Tok, /*IsReinject*/ true);
1324
44
    }
1325
274
    LLVM_FALLTHROUGH;
1326
3.82k
  case OMPD_taskyield:
1327
3.82k
  case OMPD_barrier:
1328
3.82k
  case OMPD_taskwait:
1329
3.82k
  case OMPD_cancellation_point:
1330
3.82k
  case OMPD_cancel:
1331
3.82k
  case OMPD_target_enter_data:
1332
3.82k
  case OMPD_target_exit_data:
1333
3.82k
  case OMPD_target_update:
1334
3.82k
    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1335
3.82k
        ParsedStmtContext()) {
1336
124
      Diag(Tok, diag::err_omp_immediate_directive)
1337
124
          << getOpenMPDirectiveName(DKind) << 0;
1338
124
    }
1339
3.82k
    HasAssociatedStatement = false;
1340
3.82k
    // Fall through for further analysis.
1341
3.82k
    LLVM_FALLTHROUGH;
1342
113k
  case OMPD_parallel:
1343
113k
  case OMPD_simd:
1344
113k
  case OMPD_for:
1345
113k
  case OMPD_for_simd:
1346
113k
  case OMPD_sections:
1347
113k
  case OMPD_single:
1348
113k
  case OMPD_section:
1349
113k
  case OMPD_master:
1350
113k
  case OMPD_critical:
1351
113k
  case OMPD_parallel_for:
1352
113k
  case OMPD_parallel_for_simd:
1353
113k
  case OMPD_parallel_sections:
1354
113k
  case OMPD_task:
1355
113k
  case OMPD_ordered:
1356
113k
  case OMPD_atomic:
1357
113k
  case OMPD_target:
1358
113k
  case OMPD_teams:
1359
113k
  case OMPD_taskgroup:
1360
113k
  case OMPD_target_data:
1361
113k
  case OMPD_target_parallel:
1362
113k
  case OMPD_target_parallel_for:
1363
113k
  case OMPD_taskloop:
1364
113k
  case OMPD_taskloop_simd:
1365
113k
  case OMPD_distribute:
1366
113k
  case OMPD_distribute_parallel_for:
1367
113k
  case OMPD_distribute_parallel_for_simd:
1368
113k
  case OMPD_distribute_simd:
1369
113k
  case OMPD_target_parallel_for_simd:
1370
113k
  case OMPD_target_simd:
1371
113k
  case OMPD_teams_distribute:
1372
113k
  case OMPD_teams_distribute_simd:
1373
113k
  case OMPD_teams_distribute_parallel_for_simd:
1374
113k
  case OMPD_teams_distribute_parallel_for:
1375
113k
  case OMPD_target_teams:
1376
113k
  case OMPD_target_teams_distribute:
1377
113k
  case OMPD_target_teams_distribute_parallel_for:
1378
113k
  case OMPD_target_teams_distribute_parallel_for_simd:
1379
113k
  case OMPD_target_teams_distribute_simd: {
1380
113k
    ConsumeToken();
1381
113k
    // Parse directive name of the 'critical' directive if any.
1382
113k
    if (DKind == OMPD_critical) {
1383
498
      BalancedDelimiterTracker T(*this, tok::l_paren,
1384
498
                                 tok::annot_pragma_openmp_end);
1385
498
      if (!T.consumeOpen()) {
1386
110
        if (Tok.isAnyIdentifier()) {
1387
102
          DirName =
1388
102
              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1389
102
          ConsumeAnyToken();
1390
102
        } else {
1391
8
          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1392
8
        }
1393
110
        T.consumeClose();
1394
110
      }
1395
112k
    } else if (DKind == OMPD_cancellation_point || 
DKind == OMPD_cancel112k
) {
1396
441
      CancelRegion = parseOpenMPDirectiveKind(*this);
1397
441
      if (Tok.isNot(tok::annot_pragma_openmp_end))
1398
433
        ConsumeToken();
1399
441
    }
1400
113k
1401
113k
    if (isOpenMPLoopDirective(DKind))
1402
55.4k
      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1403
113k
    if (isOpenMPSimdDirective(DKind))
1404
32.7k
      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1405
113k
    ParseScope OMPDirectiveScope(this, ScopeFlags);
1406
113k
    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1407
113k
1408
195k
    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1409
82.4k
      OpenMPClauseKind CKind =
1410
82.4k
          Tok.isAnnotation()
1411
82.4k
              ? 
OMPC_unknown0
1412
82.4k
              : FlushHasClause ? 
OMPC_flush44
1413
82.4k
                               : 
getOpenMPClauseKind(PP.getSpelling(Tok))82.4k
;
1414
82.4k
      Actions.StartOpenMPClause(CKind);
1415
82.4k
      FlushHasClause = false;
1416
82.4k
      OMPClause *Clause =
1417
82.4k
          ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1418
82.4k
      FirstClauses[CKind].setInt(true);
1419
82.4k
      if (Clause) {
1420
55.3k
        FirstClauses[CKind].setPointer(Clause);
1421
55.3k
        Clauses.push_back(Clause);
1422
55.3k
      }
1423
82.4k
1424
82.4k
      // Skip ',' if any.
1425
82.4k
      if (Tok.is(tok::comma))
1426
4.72k
        ConsumeToken();
1427
82.4k
      Actions.EndOpenMPClause();
1428
82.4k
    }
1429
113k
    // End location of the directive.
1430
113k
    EndLoc = Tok.getLocation();
1431
113k
    // Consume final annot_pragma_openmp_end.
1432
113k
    ConsumeAnnotationToken();
1433
113k
1434
113k
    // OpenMP [2.13.8, ordered Construct, Syntax]
1435
113k
    // If the depend clause is specified, the ordered construct is a stand-alone
1436
113k
    // directive.
1437
113k
    if (DKind == OMPD_ordered && 
FirstClauses[OMPC_depend].getInt()838
) {
1438
367
      if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1439
367
          ParsedStmtContext()) {
1440
24
        Diag(Loc, diag::err_omp_immediate_directive)
1441
24
            << getOpenMPDirectiveName(DKind) << 1
1442
24
            << getOpenMPClauseName(OMPC_depend);
1443
24
      }
1444
367
      HasAssociatedStatement = false;
1445
367
    }
1446
113k
1447
113k
    StmtResult AssociatedStmt;
1448
113k
    if (HasAssociatedStatement) {
1449
109k
      // The body is a block scope like in Lambdas and Blocks.
1450
109k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1451
109k
      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1452
109k
      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1453
109k
      // should have at least one compound statement scope within it.
1454
109k
      AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1455
109k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1456
109k
    } else 
if (4.19k
DKind == OMPD_target_update4.19k
||
DKind == OMPD_target_enter_data3.16k
||
1457
4.19k
               
DKind == OMPD_target_exit_data2.49k
) {
1458
2.37k
      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1459
2.37k
      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1460
2.37k
                        Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1461
2.37k
                                                  /*isStmtExpr=*/false));
1462
2.37k
      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1463
2.37k
    }
1464
113k
    Directive = Actions.ActOnOpenMPExecutableDirective(
1465
113k
        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1466
113k
        EndLoc);
1467
113k
1468
113k
    // Exit scope.
1469
113k
    Actions.EndOpenMPDSABlock(Directive.get());
1470
113k
    OMPDirectiveScope.Exit();
1471
113k
    break;
1472
113k
  }
1473
113k
  case OMPD_declare_simd:
1474
8
  case OMPD_declare_target:
1475
8
  case OMPD_end_declare_target:
1476
8
  case OMPD_requires:
1477
8
    Diag(Tok, diag::err_omp_unexpected_directive)
1478
8
        << 1 << getOpenMPDirectiveName(DKind);
1479
8
    SkipUntil(tok::annot_pragma_openmp_end);
1480
8
    break;
1481
26
  case OMPD_unknown:
1482
26
    Diag(Tok, diag::err_omp_unknown_directive);
1483
26
    SkipUntil(tok::annot_pragma_openmp_end);
1484
26
    break;
1485
114k
  }
1486
114k
  return Directive;
1487
114k
}
1488
1489
// Parses simple list:
1490
//   simple-variable-list:
1491
//         '(' id-expression {, id-expression} ')'
1492
//
1493
bool Parser::ParseOpenMPSimpleVarList(
1494
    OpenMPDirectiveKind Kind,
1495
    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1496
        Callback,
1497
2.17k
    bool AllowScopeSpecifier) {
1498
2.17k
  // Parse '('.
1499
2.17k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1500
2.17k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1501
2.17k
                         getOpenMPDirectiveName(Kind)))
1502
18
    return true;
1503
2.15k
  bool IsCorrect = true;
1504
2.15k
  bool NoIdentIsFound = true;
1505
2.15k
1506
2.15k
  // Read tokens while ')' or annot_pragma_openmp_end is not found.
1507
4.54k
  while (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::annot_pragma_openmp_end)2.40k
) {
1508
2.39k
    CXXScopeSpec SS;
1509
2.39k
    UnqualifiedId Name;
1510
2.39k
    // Read var name.
1511
2.39k
    Token PrevTok = Tok;
1512
2.39k
    NoIdentIsFound = false;
1513
2.39k
1514
2.39k
    if (AllowScopeSpecifier && 
getLangOpts().CPlusPlus1.98k
&&
1515
2.39k
        
ParseOptionalCXXScopeSpecifier(SS, nullptr, false)1.98k
) {
1516
0
      IsCorrect = false;
1517
0
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1518
0
                StopBeforeMatch);
1519
2.39k
    } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1520
2.39k
                                  nullptr, Name)) {
1521
32
      IsCorrect = false;
1522
32
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1523
32
                StopBeforeMatch);
1524
2.35k
    } else if (Tok.isNot(tok::comma) && 
Tok.isNot(tok::r_paren)2.10k
&&
1525
2.35k
               
Tok.isNot(tok::annot_pragma_openmp_end)24
) {
1526
16
      IsCorrect = false;
1527
16
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1528
16
                StopBeforeMatch);
1529
16
      Diag(PrevTok.getLocation(), diag::err_expected)
1530
16
          << tok::identifier
1531
16
          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1532
2.34k
    } else {
1533
2.34k
      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1534
2.34k
    }
1535
2.39k
    // Consume ','.
1536
2.39k
    if (Tok.is(tok::comma)) {
1537
253
      ConsumeToken();
1538
253
    }
1539
2.39k
  }
1540
2.15k
1541
2.15k
  if (NoIdentIsFound) {
1542
16
    Diag(Tok, diag::err_expected) << tok::identifier;
1543
16
    IsCorrect = false;
1544
16
  }
1545
2.15k
1546
2.15k
  // Parse ')'.
1547
2.15k
  IsCorrect = !T.consumeClose() && 
IsCorrect2.13k
;
1548
2.15k
1549
2.15k
  return !IsCorrect;
1550
2.15k
}
1551
1552
/// Parsing of OpenMP clauses.
1553
///
1554
///    clause:
1555
///       if-clause | final-clause | num_threads-clause | safelen-clause |
1556
///       default-clause | private-clause | firstprivate-clause | shared-clause
1557
///       | linear-clause | aligned-clause | collapse-clause |
1558
///       lastprivate-clause | reduction-clause | proc_bind-clause |
1559
///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1560
///       mergeable-clause | flush-clause | read-clause | write-clause |
1561
///       update-clause | capture-clause | seq_cst-clause | device-clause |
1562
///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1563
///       thread_limit-clause | priority-clause | grainsize-clause |
1564
///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1565
///       from-clause | is_device_ptr-clause | task_reduction-clause |
1566
///       in_reduction-clause | allocator-clause | allocate-clause
1567
///
1568
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1569
83.0k
                                     OpenMPClauseKind CKind, bool FirstClause) {
1570
83.0k
  OMPClause *Clause = nullptr;
1571
83.0k
  bool ErrorFound = false;
1572
83.0k
  bool WrongDirective = false;
1573
83.0k
  // Check if clause is allowed for the given directive.
1574
83.0k
  if (CKind != OMPC_unknown && 
!isAllowedClauseForDirective(DKind, CKind)80.9k
) {
1575
306
    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1576
306
                                               << getOpenMPDirectiveName(DKind);
1577
306
    ErrorFound = true;
1578
306
    WrongDirective = true;
1579
306
  }
1580
83.0k
1581
83.0k
  switch (CKind) {
1582
83.0k
  case OMPC_final:
1583
16.2k
  case OMPC_num_threads:
1584
16.2k
  case OMPC_safelen:
1585
16.2k
  case OMPC_simdlen:
1586
16.2k
  case OMPC_collapse:
1587
16.2k
  case OMPC_ordered:
1588
16.2k
  case OMPC_device:
1589
16.2k
  case OMPC_num_teams:
1590
16.2k
  case OMPC_thread_limit:
1591
16.2k
  case OMPC_priority:
1592
16.2k
  case OMPC_grainsize:
1593
16.2k
  case OMPC_num_tasks:
1594
16.2k
  case OMPC_hint:
1595
16.2k
  case OMPC_allocator:
1596
16.2k
    // OpenMP [2.5, Restrictions]
1597
16.2k
    //  At most one num_threads clause can appear on the directive.
1598
16.2k
    // OpenMP [2.8.1, simd construct, Restrictions]
1599
16.2k
    //  Only one safelen  clause can appear on a simd directive.
1600
16.2k
    //  Only one simdlen  clause can appear on a simd directive.
1601
16.2k
    //  Only one collapse clause can appear on a simd directive.
1602
16.2k
    // OpenMP [2.9.1, target data construct, Restrictions]
1603
16.2k
    //  At most one device clause can appear on the directive.
1604
16.2k
    // OpenMP [2.11.1, task Construct, Restrictions]
1605
16.2k
    //  At most one if clause can appear on the directive.
1606
16.2k
    //  At most one final clause can appear on the directive.
1607
16.2k
    // OpenMP [teams Construct, Restrictions]
1608
16.2k
    //  At most one num_teams clause can appear on the directive.
1609
16.2k
    //  At most one thread_limit clause can appear on the directive.
1610
16.2k
    // OpenMP [2.9.1, task Construct, Restrictions]
1611
16.2k
    // At most one priority clause can appear on the directive.
1612
16.2k
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1613
16.2k
    // At most one grainsize clause can appear on the directive.
1614
16.2k
    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1615
16.2k
    // At most one num_tasks clause can appear on the directive.
1616
16.2k
    // OpenMP [2.11.3, allocate Directive, Restrictions]
1617
16.2k
    // At most one allocator clause can appear on the directive.
1618
16.2k
    if (!FirstClause) {
1619
1.44k
      Diag(Tok, diag::err_omp_more_one_clause)
1620
1.44k
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1621
1.44k
      ErrorFound = true;
1622
1.44k
    }
1623
16.2k
1624
16.2k
    if (CKind == OMPC_ordered && 
PP.LookAhead(/*N=*/0).isNot(tok::l_paren)1.04k
)
1625
295
      Clause = ParseOpenMPClause(CKind, WrongDirective);
1626
15.9k
    else
1627
15.9k
      Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1628
16.2k
    break;
1629
16.2k
  case OMPC_default:
1630
1.41k
  case OMPC_proc_bind:
1631
1.41k
  case OMPC_atomic_default_mem_order:
1632
1.41k
    // OpenMP [2.14.3.1, Restrictions]
1633
1.41k
    //  Only a single default clause may be specified on a parallel, task or
1634
1.41k
    //  teams directive.
1635
1.41k
    // OpenMP [2.5, parallel Construct, Restrictions]
1636
1.41k
    //  At most one proc_bind clause can appear on the directive.
1637
1.41k
    // OpenMP [5.0, Requires directive, Restrictions]
1638
1.41k
    //  At most one atomic_default_mem_order clause can appear
1639
1.41k
    //  on the directive
1640
1.41k
    if (!FirstClause) {
1641
85
      Diag(Tok, diag::err_omp_more_one_clause)
1642
85
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1643
85
      ErrorFound = true;
1644
85
    }
1645
1.41k
1646
1.41k
    Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1647
1.41k
    break;
1648
4.12k
  case OMPC_schedule:
1649
4.12k
  case OMPC_dist_schedule:
1650
4.12k
  case OMPC_defaultmap:
1651
4.12k
    // OpenMP [2.7.1, Restrictions, p. 3]
1652
4.12k
    //  Only one schedule clause can appear on a loop directive.
1653
4.12k
    // OpenMP [2.10.4, Restrictions, p. 106]
1654
4.12k
    //  At most one defaultmap clause can appear on the directive.
1655
4.12k
    if (!FirstClause) {
1656
136
      Diag(Tok, diag::err_omp_more_one_clause)
1657
136
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1658
136
      ErrorFound = true;
1659
136
    }
1660
4.12k
    LLVM_FALLTHROUGH;
1661
4.12k
1662
9.46k
  case OMPC_if:
1663
9.46k
    Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1664
9.46k
    break;
1665
4.12k
  case OMPC_nowait:
1666
2.98k
  case OMPC_untied:
1667
2.98k
  case OMPC_mergeable:
1668
2.98k
  case OMPC_read:
1669
2.98k
  case OMPC_write:
1670
2.98k
  case OMPC_update:
1671
2.98k
  case OMPC_capture:
1672
2.98k
  case OMPC_seq_cst:
1673
2.98k
  case OMPC_threads:
1674
2.98k
  case OMPC_simd:
1675
2.98k
  case OMPC_nogroup:
1676
2.98k
  case OMPC_unified_address:
1677
2.98k
  case OMPC_unified_shared_memory:
1678
2.98k
  case OMPC_reverse_offload:
1679
2.98k
  case OMPC_dynamic_allocators:
1680
2.98k
    // OpenMP [2.7.1, Restrictions, p. 9]
1681
2.98k
    //  Only one ordered clause can appear on a loop directive.
1682
2.98k
    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1683
2.98k
    //  Only one nowait clause can appear on a for directive.
1684
2.98k
    // OpenMP [5.0, Requires directive, Restrictions]
1685
2.98k
    //   Each of the requires clauses can appear at most once on the directive.
1686
2.98k
    if (!FirstClause) {
1687
110
      Diag(Tok, diag::err_omp_more_one_clause)
1688
110
          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1689
110
      ErrorFound = true;
1690
110
    }
1691
2.98k
1692
2.98k
    Clause = ParseOpenMPClause(CKind, WrongDirective);
1693
2.98k
    break;
1694
50.7k
  case OMPC_private:
1695
50.7k
  case OMPC_firstprivate:
1696
50.7k
  case OMPC_lastprivate:
1697
50.7k
  case OMPC_shared:
1698
50.7k
  case OMPC_reduction:
1699
50.7k
  case OMPC_task_reduction:
1700
50.7k
  case OMPC_in_reduction:
1701
50.7k
  case OMPC_linear:
1702
50.7k
  case OMPC_aligned:
1703
50.7k
  case OMPC_copyin:
1704
50.7k
  case OMPC_copyprivate:
1705
50.7k
  case OMPC_flush:
1706
50.7k
  case OMPC_depend:
1707
50.7k
  case OMPC_map:
1708
50.7k
  case OMPC_to:
1709
50.7k
  case OMPC_from:
1710
50.7k
  case OMPC_use_device_ptr:
1711
50.7k
  case OMPC_is_device_ptr:
1712
50.7k
  case OMPC_allocate:
1713
50.7k
    Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1714
50.7k
    break;
1715
50.7k
  case OMPC_unknown:
1716
2.11k
    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1717
2.11k
        << getOpenMPDirectiveName(DKind);
1718
2.11k
    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1719
2.11k
    break;
1720
50.7k
  case OMPC_threadprivate:
1721
2
  case OMPC_uniform:
1722
2
    if (!WrongDirective)
1723
0
      Diag(Tok, diag::err_omp_unexpected_clause)
1724
0
          << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1725
2
    SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1726
2
    break;
1727
83.0k
  }
1728
83.0k
  return ErrorFound ? 
nullptr2.07k
:
Clause80.9k
;
1729
83.0k
}
1730
1731
/// Parses simple expression in parens for single-expression clauses of OpenMP
1732
/// constructs.
1733
/// \param RLoc Returned location of right paren.
1734
ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1735
16.1k
                                         SourceLocation &RLoc) {
1736
16.1k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1737
16.1k
  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1738
872
    return ExprError();
1739
15.2k
1740
15.2k
  SourceLocation ELoc = Tok.getLocation();
1741
15.2k
  ExprResult LHS(ParseCastExpression(
1742
15.2k
      /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1743
15.2k
  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1744
15.2k
  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1745
15.2k
1746
15.2k
  // Parse ')'.
1747
15.2k
  RLoc = Tok.getLocation();
1748
15.2k
  if (!T.consumeClose())
1749
11.7k
    RLoc = T.getCloseLocation();
1750
15.2k
1751
15.2k
  return Val;
1752
15.2k
}
1753
1754
/// Parsing of OpenMP clauses with single expressions like 'final',
1755
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1756
/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1757
///
1758
///    final-clause:
1759
///      'final' '(' expression ')'
1760
///
1761
///    num_threads-clause:
1762
///      'num_threads' '(' expression ')'
1763
///
1764
///    safelen-clause:
1765
///      'safelen' '(' expression ')'
1766
///
1767
///    simdlen-clause:
1768
///      'simdlen' '(' expression ')'
1769
///
1770
///    collapse-clause:
1771
///      'collapse' '(' expression ')'
1772
///
1773
///    priority-clause:
1774
///      'priority' '(' expression ')'
1775
///
1776
///    grainsize-clause:
1777
///      'grainsize' '(' expression ')'
1778
///
1779
///    num_tasks-clause:
1780
///      'num_tasks' '(' expression ')'
1781
///
1782
///    hint-clause:
1783
///      'hint' '(' expression ')'
1784
///
1785
///    allocator-clause:
1786
///      'allocator' '(' expression ')'
1787
///
1788
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1789
15.9k
                                               bool ParseOnly) {
1790
15.9k
  SourceLocation Loc = ConsumeToken();
1791
15.9k
  SourceLocation LLoc = Tok.getLocation();
1792
15.9k
  SourceLocation RLoc;
1793
15.9k
1794
15.9k
  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1795
15.9k
1796
15.9k
  if (Val.isInvalid())
1797
3.85k
    return nullptr;
1798
12.1k
1799
12.1k
  if (ParseOnly)
1800
32
    return nullptr;
1801
12.1k
  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1802
12.1k
}
1803
1804
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1805
///
1806
///    default-clause:
1807
///         'default' '(' 'none' | 'shared' ')
1808
///
1809
///    proc_bind-clause:
1810
///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1811
///
1812
OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1813
1.41k
                                           bool ParseOnly) {
1814
1.41k
  SourceLocation Loc = Tok.getLocation();
1815
1.41k
  SourceLocation LOpen = ConsumeToken();
1816
1.41k
  // Parse '('.
1817
1.41k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1818
1.41k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1819
1.41k
                         getOpenMPClauseName(Kind)))
1820
85
    return nullptr;
1821
1.33k
1822
1.33k
  unsigned Type = getOpenMPSimpleClauseType(
1823
1.33k
      Kind, Tok.isAnnotation() ? 
""85
:
PP.getSpelling(Tok)1.24k
);
1824
1.33k
  SourceLocation TypeLoc = Tok.getLocation();
1825
1.33k
  if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.25k
&&
1826
1.33k
      
Tok.isNot(tok::annot_pragma_openmp_end)1.25k
)
1827
1.16k
    ConsumeAnyToken();
1828
1.33k
1829
1.33k
  // Parse ')'.
1830
1.33k
  SourceLocation RLoc = Tok.getLocation();
1831
1.33k
  if (!T.consumeClose())
1832
1.16k
    RLoc = T.getCloseLocation();
1833
1.33k
1834
1.33k
  if (ParseOnly)
1835
4
    return nullptr;
1836
1.33k
  return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1837
1.33k
}
1838
1839
/// Parsing of OpenMP clauses like 'ordered'.
1840
///
1841
///    ordered-clause:
1842
///         'ordered'
1843
///
1844
///    nowait-clause:
1845
///         'nowait'
1846
///
1847
///    untied-clause:
1848
///         'untied'
1849
///
1850
///    mergeable-clause:
1851
///         'mergeable'
1852
///
1853
///    read-clause:
1854
///         'read'
1855
///
1856
///    threads-clause:
1857
///         'threads'
1858
///
1859
///    simd-clause:
1860
///         'simd'
1861
///
1862
///    nogroup-clause:
1863
///         'nogroup'
1864
///
1865
3.27k
OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1866
3.27k
  SourceLocation Loc = Tok.getLocation();
1867
3.27k
  ConsumeAnyToken();
1868
3.27k
1869
3.27k
  if (ParseOnly)
1870
117
    return nullptr;
1871
3.15k
  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1872
3.15k
}
1873
1874
1875
/// Parsing of OpenMP clauses with single expressions and some additional
1876
/// argument like 'schedule' or 'dist_schedule'.
1877
///
1878
///    schedule-clause:
1879
///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1880
///      ')'
1881
///
1882
///    if-clause:
1883
///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1884
///
1885
///    defaultmap:
1886
///      'defaultmap' '(' modifier ':' kind ')'
1887
///
1888
OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1889
9.46k
                                                      bool ParseOnly) {
1890
9.46k
  SourceLocation Loc = ConsumeToken();
1891
9.46k
  SourceLocation DelimLoc;
1892
9.46k
  // Parse '('.
1893
9.46k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1894
9.46k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
1895
9.46k
                         getOpenMPClauseName(Kind)))
1896
222
    return nullptr;
1897
9.24k
1898
9.24k
  ExprResult Val;
1899
9.24k
  SmallVector<unsigned, 4> Arg;
1900
9.24k
  SmallVector<SourceLocation, 4> KLoc;
1901
9.24k
  if (Kind == OMPC_schedule) {
1902
2.28k
    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1903
2.28k
    Arg.resize(NumberOfElements);
1904
2.28k
    KLoc.resize(NumberOfElements);
1905
2.28k
    Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1906
2.28k
    Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1907
2.28k
    Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1908
2.28k
    unsigned KindModifier = getOpenMPSimpleClauseType(
1909
2.28k
        Kind, Tok.isAnnotation() ? 
""44
:
PP.getSpelling(Tok)2.23k
);
1910
2.28k
    if (KindModifier > OMPC_SCHEDULE_unknown) {
1911
84
      // Parse 'modifier'
1912
84
      Arg[Modifier1] = KindModifier;
1913
84
      KLoc[Modifier1] = Tok.getLocation();
1914
84
      if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1915
84
          Tok.isNot(tok::annot_pragma_openmp_end))
1916
84
        ConsumeAnyToken();
1917
84
      if (Tok.is(tok::comma)) {
1918
18
        // Parse ',' 'modifier'
1919
18
        ConsumeAnyToken();
1920
18
        KindModifier = getOpenMPSimpleClauseType(
1921
18
            Kind, Tok.isAnnotation() ? 
""2
:
PP.getSpelling(Tok)16
);
1922
18
        Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1923
18
                             ? 
KindModifier14
1924
18
                             : 
(unsigned)OMPC_SCHEDULE_unknown4
;
1925
18
        KLoc[Modifier2] = Tok.getLocation();
1926
18
        if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1927
18
            Tok.isNot(tok::annot_pragma_openmp_end))
1928
16
          ConsumeAnyToken();
1929
18
      }
1930
84
      // Parse ':'
1931
84
      if (Tok.is(tok::colon))
1932
78
        ConsumeAnyToken();
1933
6
      else
1934
6
        Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1935
84
      KindModifier = getOpenMPSimpleClauseType(
1936
84
          Kind, Tok.isAnnotation() ? 
""8
:
PP.getSpelling(Tok)76
);
1937
84
    }
1938
2.28k
    Arg[ScheduleKind] = KindModifier;
1939
2.28k
    KLoc[ScheduleKind] = Tok.getLocation();
1940
2.28k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)2.23k
&&
1941
2.28k
        
Tok.isNot(tok::annot_pragma_openmp_end)2.23k
)
1942
2.18k
      ConsumeAnyToken();
1943
2.28k
    if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1944
2.28k
         
Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic1.51k
||
1945
2.28k
         
Arg[ScheduleKind] == OMPC_SCHEDULE_guided858
) &&
1946
2.28k
        
Tok.is(tok::comma)1.72k
)
1947
983
      DelimLoc = ConsumeAnyToken();
1948
6.96k
  } else if (Kind == OMPC_dist_schedule) {
1949
1.30k
    Arg.push_back(getOpenMPSimpleClauseType(
1950
1.30k
        Kind, Tok.isAnnotation() ? 
""48
:
PP.getSpelling(Tok)1.25k
));
1951
1.30k
    KLoc.push_back(Tok.getLocation());
1952
1.30k
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)1.25k
&&
1953
1.30k
        
Tok.isNot(tok::annot_pragma_openmp_end)1.25k
)
1954
1.20k
      ConsumeAnyToken();
1955
1.30k
    if (Arg.back() == OMPC_DIST_SCHEDULE_static && 
Tok.is(tok::comma)1.15k
)
1956
732
      DelimLoc = ConsumeAnyToken();
1957
5.66k
  } else if (Kind == OMPC_defaultmap) {
1958
408
    // Get a defaultmap modifier
1959
408
    Arg.push_back(getOpenMPSimpleClauseType(
1960
408
        Kind, Tok.isAnnotation() ? 
""40
:
PP.getSpelling(Tok)368
));
1961
408
    KLoc.push_back(Tok.getLocation());
1962
408
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)368
&&
1963
408
        
Tok.isNot(tok::annot_pragma_openmp_end)368
)
1964
328
      ConsumeAnyToken();
1965
408
    // Parse ':'
1966
408
    if (Tok.is(tok::colon))
1967
128
      ConsumeAnyToken();
1968
280
    else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1969
200
      Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1970
408
    // Get a defaultmap kind
1971
408
    Arg.push_back(getOpenMPSimpleClauseType(
1972
408
        Kind, Tok.isAnnotation() ? 
""160
:
PP.getSpelling(Tok)248
));
1973
408
    KLoc.push_back(Tok.getLocation());
1974
408
    if (Tok.isNot(tok::r_paren) && 
Tok.isNot(tok::comma)328
&&
1975
408
        
Tok.isNot(tok::annot_pragma_openmp_end)248
)
1976
88
      ConsumeAnyToken();
1977
5.25k
  } else {
1978
5.25k
    assert(Kind == OMPC_if);
1979
5.25k
    KLoc.push_back(Tok.getLocation());
1980
5.25k
    TentativeParsingAction TPA(*this);
1981
5.25k
    Arg.push_back(parseOpenMPDirectiveKind(*this));
1982
5.25k
    if (Arg.back() != OMPD_unknown) {
1983
2.66k
      ConsumeToken();
1984
2.66k
      if (Tok.is(tok::colon) && 
getLangOpts().OpenMP > 402.60k
) {
1985
2.60k
        TPA.Commit();
1986
2.60k
        DelimLoc = ConsumeToken();
1987
2.60k
      } else {
1988
52
        TPA.Revert();
1989
52
        Arg.back() = OMPD_unknown;
1990
52
      }
1991
2.66k
    } else {
1992
2.59k
      TPA.Revert();
1993
2.59k
    }
1994
5.25k
  }
1995
9.24k
1996
9.24k
  bool NeedAnExpression = (Kind == OMPC_schedule && 
DelimLoc.isValid()2.28k
) ||
1997
9.24k
                          
(8.26k
Kind == OMPC_dist_schedule8.26k
&&
DelimLoc.isValid()1.30k
) ||
1998
9.24k
                          
Kind == OMPC_if7.52k
;
1999
9.24k
  if (NeedAnExpression) {
2000
6.96k
    SourceLocation ELoc = Tok.getLocation();
2001
6.96k
    ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
2002
6.96k
    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
2003
6.96k
    Val =
2004
6.96k
        Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2005
6.96k
  }
2006
9.24k
2007
9.24k
  // Parse ')'.
2008
9.24k
  SourceLocation RLoc = Tok.getLocation();
2009
9.24k
  if (!T.consumeClose())
2010
7.76k
    RLoc = T.getCloseLocation();
2011
9.24k
2012
9.24k
  if (NeedAnExpression && 
Val.isInvalid()6.96k
)
2013
624
    return nullptr;
2014
8.61k
2015
8.61k
  if (ParseOnly)
2016
2
    return nullptr;
2017
8.61k
  return Actions.ActOnOpenMPSingleExprWithArgClause(
2018
8.61k
      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2019
8.61k
}
2020
2021
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2022
15.9k
                             UnqualifiedId &ReductionId) {
2023
15.9k
  if (ReductionIdScopeSpec.isEmpty()) {
2024
15.9k
    auto OOK = OO_None;
2025
15.9k
    switch (P.getCurToken().getKind()) {
2026
15.9k
    case tok::plus:
2027
6.70k
      OOK = OO_Plus;
2028
6.70k
      break;
2029
15.9k
    case tok::minus:
2030
954
      OOK = OO_Minus;
2031
954
      break;
2032
15.9k
    case tok::star:
2033
1.05k
      OOK = OO_Star;
2034
1.05k
      break;
2035
15.9k
    case tok::amp:
2036
524
      OOK = OO_Amp;
2037
524
      break;
2038
15.9k
    case tok::pipe:
2039
463
      OOK = OO_Pipe;
2040
463
      break;
2041
15.9k
    case tok::caret:
2042
846
      OOK = OO_Caret;
2043
846
      break;
2044
15.9k
    case tok::ampamp:
2045
1.31k
      OOK = OO_AmpAmp;
2046
1.31k
      break;
2047
15.9k
    case tok::pipepipe:
2048
388
      OOK = OO_PipePipe;
2049
388
      break;
2050
15.9k
    default:
2051
3.69k
      break;
2052
15.9k
    }
2053
15.9k
    if (OOK != OO_None) {
2054
12.2k
      SourceLocation OpLoc = P.ConsumeToken();
2055
12.2k
      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
2056
12.2k
      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2057
12.2k
      return false;
2058
12.2k
    }
2059
3.71k
  }
2060
3.71k
  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2061
3.71k
                              /*AllowDestructorName*/ false,
2062
3.71k
                              /*AllowConstructorName*/ false,
2063
3.71k
                              /*AllowDeductionGuide*/ false,
2064
3.71k
                              nullptr, nullptr, ReductionId);
2065
3.71k
}
2066
2067
/// Checks if the token is a valid map-type-modifier.
2068
3.38k
static OpenMPMapModifierKind isMapModifier(Parser &P) {
2069
3.38k
  Token Tok = P.getCurToken();
2070
3.38k
  if (!Tok.is(tok::identifier))
2071
40
    return OMPC_MAP_MODIFIER_unknown;
2072
3.34k
2073
3.34k
  Preprocessor &PP = P.getPreprocessor();
2074
3.34k
  OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2075
3.34k
      getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2076
3.34k
  return TypeModifier;
2077
3.34k
}
2078
2079
/// Parse the mapper modifier in map, to, and from clauses.
2080
334
bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2081
334
  // Parse '('.
2082
334
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2083
334
  if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2084
40
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2085
40
              StopBeforeMatch);
2086
40
    return true;
2087
40
  }
2088
294
  // Parse mapper-identifier
2089
294
  if (getLangOpts().CPlusPlus)
2090
248
    ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2091
248
                                   /*ObjectType=*/nullptr,
2092
248
                                   /*EnteringContext=*/false);
2093
294
  if (Tok.isNot(tok::identifier) && 
Tok.isNot(tok::kw_default)80
) {
2094
68
    Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2095
68
    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2096
68
              StopBeforeMatch);
2097
68
    return true;
2098
68
  }
2099
226
  auto &DeclNames = Actions.getASTContext().DeclarationNames;
2100
226
  Data.ReductionOrMapperId = DeclarationNameInfo(
2101
226
      DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2102
226
  ConsumeToken();
2103
226
  // Parse ')'.
2104
226
  return T.consumeClose();
2105
226
}
2106
2107
/// Parse map-type-modifiers in map clause.
2108
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2109
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2110
2.88k
bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2111
3.50k
  while (getCurToken().isNot(tok::colon)) {
2112
3.38k
    OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2113
3.38k
    if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2114
3.38k
        
TypeModifier == OMPC_MAP_MODIFIER_close3.00k
) {
2115
466
      Data.MapTypeModifiers.push_back(TypeModifier);
2116
466
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2117
466
      ConsumeToken();
2118
2.92k
    } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2119
104
      Data.MapTypeModifiers.push_back(TypeModifier);
2120
104
      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2121
104
      ConsumeToken();
2122
104
      if (parseMapperModifier(Data))
2123
20
        return true;
2124
2.81k
    } else {
2125
2.81k
      // For the case of unknown map-type-modifier or a map-type.
2126
2.81k
      // Map-type is followed by a colon; the function returns when it
2127
2.81k
      // encounters a token followed by a colon.
2128
2.81k
      if (Tok.is(tok::comma)) {
2129
12
        Diag(Tok, diag::err_omp_map_type_modifier_missing);
2130
12
        ConsumeToken();
2131
12
        continue;
2132
12
      }
2133
2.80k
      // Potential map-type token as it is followed by a colon.
2134
2.80k
      if (PP.LookAhead(0).is(tok::colon))
2135
2.75k
        return false;
2136
54
      Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2137
54
      ConsumeToken();
2138
54
    }
2139
3.38k
    
if (604
getCurToken().is(tok::comma)604
)
2140
402
      ConsumeToken();
2141
604
  }
2142
2.88k
  
return false114
;
2143
2.88k
}
2144
2145
/// Checks if the token is a valid map-type.
2146
2.75k
static OpenMPMapClauseKind isMapType(Parser &P) {
2147
2.75k
  Token Tok = P.getCurToken();
2148
2.75k
  // The map-type token can be either an identifier or the C++ delete keyword.
2149
2.75k
  if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2150
0
    return OMPC_MAP_unknown;
2151
2.75k
  Preprocessor &PP = P.getPreprocessor();
2152
2.75k
  OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2153
2.75k
      getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2154
2.75k
  return MapType;
2155
2.75k
}
2156
2157
/// Parse map-type in map clause.
2158
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2159
/// where, map-type ::= to | from | tofrom | alloc | release | delete
2160
2.86k
static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2161
2.86k
  Token Tok = P.getCurToken();
2162
2.86k
  if (Tok.is(tok::colon)) {
2163
114
    P.Diag(Tok, diag::err_omp_map_type_missing);
2164
114
    return;
2165
114
  }
2166
2.75k
  Data.MapType = isMapType(P);
2167
2.75k
  if (Data.MapType == OMPC_MAP_unknown)
2168
66
    P.Diag(Tok, diag::err_omp_unknown_map_type);
2169
2.75k
  P.ConsumeToken();
2170
2.75k
}
2171
2172
/// Parses clauses with list.
2173
bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2174
                                OpenMPClauseKind Kind,
2175
                                SmallVectorImpl<Expr *> &Vars,
2176
51.0k
                                OpenMPVarListDataTy &Data) {
2177
51.0k
  UnqualifiedId UnqualifiedReductionId;
2178
51.0k
  bool InvalidReductionId = false;
2179
51.0k
  bool IsInvalidMapperModifier = false;
2180
51.0k
2181
51.0k
  // Parse '('.
2182
51.0k
  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2183
51.0k
  if (T.expectAndConsume(diag::err_expected_lparen_after,
2184
51.0k
                         getOpenMPClauseName(Kind)))
2185
1.77k
    return true;
2186
49.3k
2187
49.3k
  bool NeedRParenForLinear = false;
2188
49.3k
  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2189
49.3k
                                  tok::annot_pragma_openmp_end);
2190
49.3k
  // Handle reduction-identifier for reduction clause.
2191
49.3k
  if (Kind == OMPC_reduction || 
Kind == OMPC_task_reduction35.6k
||
2192
49.3k
      
Kind == OMPC_in_reduction34.6k
) {
2193
15.9k
    ColonProtectionRAIIObject ColonRAII(*this);
2194
15.9k
    if (getLangOpts().CPlusPlus)
2195
15.8k
      ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2196
15.8k
                                     /*ObjectType=*/nullptr,
2197
15.8k
                                     /*EnteringContext=*/false);
2198
15.9k
    InvalidReductionId = ParseReductionId(
2199
15.9k
        *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2200
15.9k
    if (InvalidReductionId) {
2201
1.36k
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2202
1.36k
                StopBeforeMatch);
2203
1.36k
    }
2204
15.9k
    if (Tok.is(tok::colon))
2205
14.0k
      Data.ColonLoc = ConsumeToken();
2206
1.94k
    else
2207
1.94k
      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2208
15.9k
    if (!InvalidReductionId)
2209
14.6k
      Data.ReductionOrMapperId =
2210
14.6k
          Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2211
33.3k
  } else if (Kind == OMPC_depend) {
2212
2.68k
  // Handle dependency type for depend clause.
2213
2.68k
    ColonProtectionRAIIObject ColonRAII(*this);
2214
2.68k
    Data.DepKind =
2215
2.68k
        static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2216
2.68k
            Kind, Tok.is(tok::identifier) ? 
PP.getSpelling(Tok)2.60k
:
""80
));
2217
2.68k
    Data.DepLinMapLoc = Tok.getLocation();
2218
2.68k
2219
2.68k
    if (Data.DepKind == OMPC_DEPEND_unknown) {
2220
114
      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2221
114
                StopBeforeMatch);
2222
2.56k
    } else {
2223
2.56k
      ConsumeToken();
2224
2.56k
      // Special processing for depend(source) clause.
2225
2.56k
      if (DKind == OMPD_ordered && 
Data.DepKind == OMPC_DEPEND_source395
) {
2226
161
        // Parse ')'.
2227
161
        T.consumeClose();
2228
161
        return false;
2229
161
      }
2230
2.52k
    }
2231
2.52k
    if (Tok.is(tok::colon)) {
2232
2.32k
      Data.ColonLoc = ConsumeToken();
2233
2.32k
    } else {
2234
194
      Diag(Tok, DKind == OMPD_ordered ? 
diag::warn_pragma_expected_colon_r_paren24
2235
194
                                      : 
diag::warn_pragma_expected_colon170
)
2236
194
          << "dependency type";
2237
194
    }
2238
30.6k
  } else if (Kind == OMPC_linear) {
2239
2.26k
    // Try to parse modifier if any.
2240
2.26k
    if (Tok.is(tok::identifier) && 
PP.LookAhead(0).is(tok::l_paren)2.02k
) {
2241
184
      Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2242
184
          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2243
184
      Data.DepLinMapLoc = ConsumeToken();
2244
184
      LinearT.consumeOpen();
2245
184
      NeedRParenForLinear = true;
2246
184
    }
2247
28.4k
  } else if (Kind == OMPC_map) {
2248
6.30k
    // Handle map type for map clause.
2249
6.30k
    ColonProtectionRAIIObject ColonRAII(*this);
2250
6.30k
2251
6.30k
    // The first identifier may be a list item, a map-type or a
2252
6.30k
    // map-type-modifier. The map-type can also be delete which has the same
2253
6.30k
    // spelling of the C++ delete keyword.
2254
6.30k
    Data.DepLinMapLoc = Tok.getLocation();
2255
6.30k
2256
6.30k
    // Check for presence of a colon in the map clause.
2257
6.30k
    TentativeParsingAction TPA(*this);
2258
6.30k
    bool ColonPresent = false;
2259
6.30k
    if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2260
6.30k
        StopBeforeMatch)) {
2261
6.30k
      if (Tok.is(tok::colon))
2262
2.88k
        ColonPresent = true;
2263
6.30k
    }
2264
6.30k
    TPA.Revert();
2265
6.30k
    // Only parse map-type-modifier[s] and map-type if a colon is present in
2266
6.30k
    // the map clause.
2267
6.30k
    if (ColonPresent) {
2268
2.88k
      IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2269
2.88k
      if (!IsInvalidMapperModifier)
2270
2.86k
        parseMapType(*this, Data);
2271
20
      else
2272
20
        SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2273
2.88k
    }
2274
6.30k
    if (Data.MapType == OMPC_MAP_unknown) {
2275
3.62k
      Data.MapType = OMPC_MAP_tofrom;
2276
3.62k
      Data.IsMapTypeImplicit = true;
2277
3.62k
    }
2278
6.30k
2279
6.30k
    if (Tok.is(tok::colon))
2280
2.88k
      Data.ColonLoc = ConsumeToken();
2281
22.1k
  } else if (Kind == OMPC_to || 
Kind == OMPC_from21.4k
) {
2282
1.03k
    if (Tok.is(tok::identifier)) {
2283
1.01k
      bool IsMapperModifier = false;
2284
1.01k
      if (Kind == OMPC_to) {
2285
651
        auto Modifier = static_cast<OpenMPToModifierKind>(
2286
651
            getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2287
651
        if (Modifier == OMPC_TO_MODIFIER_mapper)
2288
114
          IsMapperModifier = true;
2289
651
      } else {
2290
364
        auto Modifier = static_cast<OpenMPFromModifierKind>(
2291
364
            getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2292
364
        if (Modifier == OMPC_FROM_MODIFIER_mapper)
2293
116
          IsMapperModifier = true;
2294
364
      }
2295
1.01k
      if (IsMapperModifier) {
2296
230
        // Parse the mapper modifier.
2297
230
        ConsumeToken();
2298
230
        IsInvalidMapperModifier = parseMapperModifier(Data);
2299
230
        if (Tok.isNot(tok::colon)) {
2300
46
          if (!IsInvalidMapperModifier)
2301
14
            Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2302
46
          SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2303
46
                    StopBeforeMatch);
2304
46
        }
2305
230
        // Consume ':'.
2306
230
        if (Tok.is(tok::colon))
2307
198
          ConsumeToken();
2308
230
      }
2309
1.01k
    }
2310
21.0k
  } else if (Kind == OMPC_allocate) {
2311
886
    // Handle optional allocator expression followed by colon delimiter.
2312
886
    ColonProtectionRAIIObject ColonRAII(*this);
2313
886
    TentativeParsingAction TPA(*this);
2314
886
    ExprResult Tail =
2315
886
        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2316
886
    Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
2317
886
                                       /*DiscardedValue=*/false);
2318
886
    if (Tail.isUsable()) {
2319
496
      if (Tok.is(tok::colon)) {
2320
224
        Data.TailExpr = Tail.get();
2321
224
        Data.ColonLoc = ConsumeToken();
2322
224
        TPA.Commit();
2323
272
      } else {
2324
272
        // colon not found, no allocator specified, parse only list of
2325
272
        // variables.
2326
272
        TPA.Revert();
2327
272
      }
2328
496
    } else {
2329
390
      // Parsing was unsuccessfull, revert and skip to the end of clause or
2330
390
      // directive.
2331
390
      TPA.Revert();
2332
390
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2333
390
                StopBeforeMatch);
2334
390
    }
2335
886
  }
2336
49.3k
2337
49.3k
  bool IsComma =
2338
49.1k
      (Kind != OMPC_reduction && 
Kind != OMPC_task_reduction35.4k
&&
2339
49.1k
       
Kind != OMPC_in_reduction34.4k
&&
Kind != OMPC_depend33.1k
&&
Kind != OMPC_map30.6k
) ||
2340
49.1k
      
(24.7k
Kind == OMPC_reduction24.7k
&&
!InvalidReductionId13.7k
) ||
2341
49.1k
      
(12.2k
Kind == OMPC_map12.2k
&&
Data.MapType != OMPC_MAP_unknown6.30k
) ||
2342
49.1k
      
(5.98k
Kind == OMPC_depend5.98k
&&
Data.DepKind != OMPC_DEPEND_unknown2.52k
);
2343
49.1k
  const bool MayHaveTail = (Kind == OMPC_linear || 
Kind == OMPC_aligned46.8k
);
2344
116k
  while (IsComma || 
(51.5k
Tok.isNot(tok::r_paren)51.5k
&&
Tok.isNot(tok::colon)7.90k
&&
2345
66.8k
                     
Tok.isNot(tok::annot_pragma_openmp_end)6.48k
)) {
2346
66.8k
    ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
2347
66.8k
    // Parse variable
2348
66.8k
    ExprResult VarExpr =
2349
66.8k
        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2350
66.8k
    if (VarExpr.isUsable()) {
2351
60.4k
      Vars.push_back(VarExpr.get());
2352
60.4k
    } else {
2353
6.40k
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2354
6.40k
                StopBeforeMatch);
2355
6.40k
    }
2356
66.8k
    // Skip ',' if any
2357
66.8k
    IsComma = Tok.is(tok::comma);
2358
66.8k
    if (IsComma)
2359
18.9k
      ConsumeToken();
2360
47.9k
    else if (Tok.isNot(tok::r_paren) &&
2361
47.9k
             
Tok.isNot(tok::annot_pragma_openmp_end)5.18k
&&
2362
47.9k
             
(1.56k
!MayHaveTail1.56k
||
Tok.isNot(tok::colon)1.42k
))
2363
144
      Diag(Tok, diag::err_omp_expected_punc)
2364
144
          << ((Kind == OMPC_flush) ? 
getOpenMPDirectiveName(OMPD_flush)0
2365
144
                                   : getOpenMPClauseName(Kind))
2366
144
          << (Kind == OMPC_flush);
2367
66.8k
  }
2368
49.1k
2369
49.1k
  // Parse ')' for linear clause with modifier.
2370
49.1k
  if (NeedRParenForLinear)
2371
184
    LinearT.consumeClose();
2372
49.1k
2373
49.1k
  // Parse ':' linear-step (or ':' alignment).
2374
49.1k
  const bool MustHaveTail = MayHaveTail && 
Tok.is(tok::colon)3.90k
;
2375
49.1k
  if (MustHaveTail) {
2376
1.49k
    Data.ColonLoc = Tok.getLocation();
2377
1.49k
    SourceLocation ELoc = ConsumeToken();
2378
1.49k
    ExprResult Tail = ParseAssignmentExpression();
2379
1.49k
    Tail =
2380
1.49k
        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
2381
1.49k
    if (Tail.isUsable())
2382
1.45k
      Data.TailExpr = Tail.get();
2383
40
    else
2384
40
      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2385
40
                StopBeforeMatch);
2386
1.49k
  }
2387
49.1k
2388
49.1k
  // Parse ')'.
2389
49.1k
  Data.RLoc = Tok.getLocation();
2390
49.1k
  if (!T.consumeClose())
2391
44.9k
    Data.RLoc = T.getCloseLocation();
2392
49.1k
  return (Kind == OMPC_depend && 
Data.DepKind != OMPC_DEPEND_unknown2.52k
&&
2393
49.1k
          
Vars.empty()2.40k
) ||
2394
49.1k
         
(48.6k
Kind != OMPC_depend48.6k
&&
Kind != OMPC_map46.6k
&&
Vars.empty()40.3k
) ||
2395
49.1k
         
(43.5k
MustHaveTail43.5k
&&
!Data.TailExpr1.49k
) ||
InvalidReductionId43.4k
||
2396
49.1k
         
IsInvalidMapperModifier43.2k
;
2397
49.3k
}
2398
2399
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2400
/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2401
/// 'in_reduction'.
2402
///
2403
///    private-clause:
2404
///       'private' '(' list ')'
2405
///    firstprivate-clause:
2406
///       'firstprivate' '(' list ')'
2407
///    lastprivate-clause:
2408
///       'lastprivate' '(' list ')'
2409
///    shared-clause:
2410
///       'shared' '(' list ')'
2411
///    linear-clause:
2412
///       'linear' '(' linear-list [ ':' linear-step ] ')'
2413
///    aligned-clause:
2414
///       'aligned' '(' list [ ':' alignment ] ')'
2415
///    reduction-clause:
2416
///       'reduction' '(' reduction-identifier ':' list ')'
2417
///    task_reduction-clause:
2418
///       'task_reduction' '(' reduction-identifier ':' list ')'
2419
///    in_reduction-clause:
2420
///       'in_reduction' '(' reduction-identifier ':' list ')'
2421
///    copyprivate-clause:
2422
///       'copyprivate' '(' list ')'
2423
///    flush-clause:
2424
///       'flush' '(' list ')'
2425
///    depend-clause:
2426
///       'depend' '(' in | out | inout : list | source ')'
2427
///    map-clause:
2428
///       'map' '(' [ [ always [,] ] [ close [,] ]
2429
///          [ mapper '(' mapper-identifier ')' [,] ]
2430
///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2431
///    to-clause:
2432
///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2433
///    from-clause:
2434
///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2435
///    use_device_ptr-clause:
2436
///       'use_device_ptr' '(' list ')'
2437
///    is_device_ptr-clause:
2438
///       'is_device_ptr' '(' list ')'
2439
///    allocate-clause:
2440
///       'allocate' '(' [ allocator ':' ] list ')'
2441
///
2442
/// For 'linear' clause linear-list may have the following forms:
2443
///  list
2444
///  modifier(list)
2445
/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
2446
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2447
                                            OpenMPClauseKind Kind,
2448
50.7k
                                            bool ParseOnly) {
2449
50.7k
  SourceLocation Loc = Tok.getLocation();
2450
50.7k
  SourceLocation LOpen = ConsumeToken();
2451
50.7k
  SmallVector<Expr *, 4> Vars;
2452
50.7k
  OpenMPVarListDataTy Data;
2453
50.7k
2454
50.7k
  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2455
7.70k
    return nullptr;
2456
43.0k
2457
43.0k
  if (ParseOnly)
2458
147
    return nullptr;
2459
42.9k
  OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
2460
42.9k
  return Actions.ActOnOpenMPVarListClause(
2461
42.9k
      Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2462
42.9k
      Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2463
42.9k
      Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2464
42.9k
      Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2465
42.9k
}
2466