Coverage Report

Created: 2022-01-18 06:27

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