Coverage Report

Created: 2020-03-28 08:29

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