Coverage Report

Created: 2020-02-15 09:57

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