Coverage Report

Created: 2021-09-21 08:58

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