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