Coverage Report

Created: 2022-05-17 06:19

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